summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoramarinichev@chromium.org <amarinichev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-23 23:17:56 +0000
committeramarinichev@chromium.org <amarinichev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-23 23:17:56 +0000
commitbc3ef7faa993606415465cc3a036b5f3af9de660 (patch)
tree69c51db29737194ed207c84c6235a18779a3e91c
parent1eb71d721dee36e8f386bdc0900f915a0813981a (diff)
downloadchromium_src-bc3ef7faa993606415465cc3a036b5f3af9de660.zip
chromium_src-bc3ef7faa993606415465cc3a036b5f3af9de660.tar.gz
chromium_src-bc3ef7faa993606415465cc3a036b5f3af9de660.tar.bz2
Adds --convert-cg-to-glsl to the Collada converter tool.
Review URL: http://codereview.chromium.org/1750008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45514 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-xo3d/cg_to_glsl/convert.py54
-rw-r--r--o3d/converter/cross/converter.cc2
-rw-r--r--o3d/converter/cross/converter.h10
-rw-r--r--o3d/converter/cross/converter_main.cc14
-rw-r--r--o3d/import/cross/collada.cc27
-rw-r--r--o3d/import/cross/collada.h10
6 files changed, 90 insertions, 27 deletions
diff --git a/o3d/cg_to_glsl/convert.py b/o3d/cg_to_glsl/convert.py
index 566b0fc..1aa28f1 100755
--- a/o3d/cg_to_glsl/convert.py
+++ b/o3d/cg_to_glsl/convert.py
@@ -25,7 +25,12 @@ import sys
# instruction and keeping the MatrixLoadOrder instruction as is.
-CGC = '/usr/bin/cgc'
+if os.name == 'nt':
+ CGC = 'c:/Program Files/NVIDIA Corporation/Cg/bin/cgc.exe'
+ if not os.path.exists(CGC):
+ CGC = 'c:/Program Files (x86)/NVIDIA Corporation/Cg/bin/cgc.exe'
+else:
+ CGC = '/usr/bin/cgc'
# cgc complains about TANGENT1 and BINORMAL1 semantics, so we hack it by
# replacing standard semantics with ATTR8-ATTR12 and then renaming them back to
@@ -139,7 +144,7 @@ def fix_glsl_body(body, input_mapping):
def fix_glsl(glsl_shader):
- header, body = re.split(r'\n\n', glsl_shader, 1)
+ header, body = re.split(os.linesep*2, glsl_shader, 1)
assert all(l.startswith('//') for l in header.splitlines())
input_mapping = get_input_mapping(header)
return header + '\n\n' + fix_glsl_body(body, input_mapping)
@@ -156,15 +161,15 @@ def cg_to_glsl(cg_shader):
vertex_entry = re.search(r'#o3d\s+VertexShaderEntryPoint\s+(\w+)',
cg_shader).group(1)
- p = subprocess.Popen(CGC+' -profile glslv -entry %s' % vertex_entry,
- shell=True,
+ p = subprocess.Popen([CGC]+('-profile glslv -entry %s' %
+ vertex_entry).split(' '),
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
glsl_vertex, err_v = p.communicate(cg_shader)
fragment_entry = re.search(r'#o3d\s+PixelShaderEntryPoint\s+(\w+)',
cg_shader).group(1)
- p = subprocess.Popen(CGC+' -profile glslf -entry %s' % fragment_entry,
- shell=True,
+ p = subprocess.Popen([CGC]+('-profile glslf -entry %s' %
+ fragment_entry).split(' '),
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
glsl_fragment, err_f = p.communicate(cg_shader)
@@ -185,8 +190,6 @@ def check_cg():
if not os.path.exists(CGC):
print >>sys.stderr, CGC+' is not found, use --cgc option to specify its'
print >>sys.stderr, 'location. You may need to install nvidia cg toolkit.'
- print >>sys.stderr, 'In Ubuntu distribution it can be done by running:'
- print >>sys.stderr, ' "apt-get install nvidia-cg-toolkit"'
sys.exit(1)
@@ -204,19 +207,22 @@ def main(cg_shader):
if __name__ == '__main__':
- cmdline_parser = optparse.OptionParser()
- cmdline_parser.add_option('--cgc', dest='CGC', default='/usr/bin/cgc',
- help='path to cgc [default: %default]')
- options, args = cmdline_parser.parse_args()
- CGC = options.CGC
- check_cg()
-
- try:
- input = sys.stdin.read()
- except KeyboardInterrupt:
- input = None
-
- if not input:
- cmdline_parser.print_help()
- else:
- main(input)
+ cmdline_parser = optparse.OptionParser()
+ cmdline_parser.add_option('-i', dest='file', default=None,
+ help='input shader; standard input if omitted')
+ cmdline_parser.add_option('--cgc', dest='CGC', default=CGC,
+ help='path to cgc [default: %default]')
+ options, args = cmdline_parser.parse_args()
+ CGC = options.CGC
+ check_cg()
+
+ try:
+ f = sys.stdin if options.file is None else open(options.file)
+ input = f.read()
+ except KeyboardInterrupt:
+ input = None
+
+ if not input:
+ cmdline_parser.print_help()
+ else:
+ main(input)
diff --git a/o3d/converter/cross/converter.cc b/o3d/converter/cross/converter.cc
index f039f5de..4726392 100644
--- a/o3d/converter/cross/converter.cc
+++ b/o3d/converter/cross/converter.cc
@@ -299,6 +299,8 @@ bool Convert(const FilePath& in_filename,
collada_options.file_paths = options.file_paths;
collada_options.up_axis = options.up_axis;
collada_options.convert_dds_to_png = options.convert_dds_to_png;
+ collada_options.convert_cg_to_glsl = options.convert_cg_to_glsl;
+ collada_options.converter_tool = options.converter_tool;
Collada collada(pack.Get(), collada_options);
bool result = collada.ImportFile(in_filename, root, param_float);
if (!result || !error_collector.errors().empty()) {
diff --git a/o3d/converter/cross/converter.h b/o3d/converter/cross/converter.h
index 7a289ee..69e801b 100644
--- a/o3d/converter/cross/converter.h
+++ b/o3d/converter/cross/converter.h
@@ -56,7 +56,9 @@ struct Options {
keep_filters(false),
keep_materials(false),
archive(true),
- convert_dds_to_png(false) {
+ convert_dds_to_png(false),
+ convert_cg_to_glsl(false),
+ converter_tool() {
}
// A list of paths to search for assets..
@@ -95,6 +97,12 @@ struct Options {
// True means convert DDS files to PNGs. For cube map textures, this
// implies writing six separate PNGs.
bool convert_dds_to_png;
+
+ // True means convert CG shaders go GLSL using external cgc tool.
+ bool convert_cg_to_glsl;
+
+ // Path to shader converter tool.
+ FilePath converter_tool;
};
// Converts the given file for use in O3D. This is done by
diff --git a/o3d/converter/cross/converter_main.cc b/o3d/converter/cross/converter_main.cc
index 9af930f..ab72b61 100644
--- a/o3d/converter/cross/converter_main.cc
+++ b/o3d/converter/cross/converter_main.cc
@@ -69,6 +69,9 @@ int CrossMain(int argc, char**argv) {
const CommandLine* command_line = CommandLine::ForCurrentProcess();
FilePath in_filename, out_filename;
+ const FilePath converter_tool = FilePath(argv[0]).DirName().Append(
+ o3d::UTF8ToFilePath("convert.py"));
+
std::vector<std::wstring> values = command_line->GetLooseValues();
if (values.size() == 1) {
@@ -109,7 +112,12 @@ int CrossMain(int argc, char**argv) {
<< " directory named archive/ and writes files inside.\n"
<< "--convert-dds-to-png\n"
<< " Convert all DDS textures to PNGs. For cube map textures,\n"
- << " writes six separate PNGs with suffixes _posx, _negx, etc.\n";
+ << " writes six separate PNGs with suffixes _posx, _negx, etc.\n"
+ << "--convert-cg-to-glsl\n"
+ << " Convert shaders using an external tool.\n"
+ << "--converter-tool=<filename> [default: "
+ << converter_tool.value() << "]\n"
+ << " Specifies the shader converter tool.\n";
return EXIT_FAILURE;
}
@@ -119,6 +127,10 @@ int CrossMain(int argc, char**argv) {
options.binary = !command_line->HasSwitch("no-binary");
options.archive = !command_line->HasSwitch("no-archive");
options.convert_dds_to_png = command_line->HasSwitch("convert-dds-to-png");
+ options.convert_cg_to_glsl = command_line->HasSwitch("convert-cg-to-glsl");
+ options.converter_tool = command_line->HasSwitch("converter-tool") ?
+ o3d::WideToFilePath(command_line->GetSwitchValue("converter-tool")) :
+ converter_tool;
if (command_line->HasSwitch("base-path")) {
options.base_path = o3d::WideToFilePath(
command_line->GetSwitchValue("base-path"));
diff --git a/o3d/import/cross/collada.cc b/o3d/import/cross/collada.cc
index cfc64b3..cb6dcac 100644
--- a/o3d/import/cross/collada.cc
+++ b/o3d/import/cross/collada.cc
@@ -35,6 +35,7 @@
#include "base/file_path.h"
#include "base/file_util.h"
+#include "base/process_util.h"
#include "base/string_util.h"
#include "core/cross/class_manager.h"
#include "core/cross/curve.h"
@@ -509,6 +510,26 @@ void BindParams(Param* input_param,
bool ok = input_param->Bind(output_param);
DCHECK_EQ(ok, true);
}
+
+// Runs effect_string through the filter, replacing it in place.
+bool ConvertCgToGlsl(const FilePath& converter, String* effect_string) {
+ FilePath temporary_file_name;
+ FILE* temporary_file = file_util::CreateAndOpenTemporaryFile(
+ &temporary_file_name);
+ if (!temporary_file)
+ return false;
+
+ fwrite(effect_string->c_str(), 1, effect_string->length(), temporary_file);
+ file_util::CloseFile(temporary_file);
+
+ CommandLine cmd_line(converter);
+ cmd_line.AppendLooseValue(L"-i");
+ cmd_line.AppendLooseValue(o3d::FilePathToWide(temporary_file_name));
+ bool rc = ::base::GetAppOutput(cmd_line, effect_string);
+
+ file_util::Delete(temporary_file_name, false);
+ return rc;
+}
} // namespace anonymous
bool Collada::BuildFloatAnimation(ParamFloat* result,
@@ -2178,6 +2199,12 @@ Effect* Collada::BuildEffect(FCDocument* doc, FCDEffect* collada_effect) {
<< "'";
return NULL;
}
+
+ if (options_.convert_cg_to_glsl) {
+ if (!ConvertCgToGlsl(options_.converter_tool, &effect_string))
+ O3D_ERROR(service_locator_) << "Shader conversion failed.";
+ }
+
if (options_.keep_original_data) {
// Cache the original data by URI so we can recover it later.
original_data_map_.AddData(file_path, effect_string, service_locator_);
diff --git a/o3d/import/cross/collada.h b/o3d/import/cross/collada.h
index e0c1a02..18b5937 100644
--- a/o3d/import/cross/collada.h
+++ b/o3d/import/cross/collada.h
@@ -162,7 +162,9 @@ class Collada {
condition_document(false),
up_axis(0.0f, 0.0f, 0.0f),
base_path(FilePath::kCurrentDirectory),
- convert_dds_to_png(false) {}
+ convert_dds_to_png(false),
+ convert_cg_to_glsl(false),
+ converter_tool() {}
// Whether or not to generate mip-maps on the textures we load.
bool generate_mipmaps;
@@ -187,6 +189,12 @@ class Collada {
// True means convert DDS files to PNGs. For cube map textures, this
// implies writing six separate PNGs.
bool convert_dds_to_png;
+
+ // If true, run converter tool on shaders.
+ bool convert_cg_to_glsl;
+
+ // Path to the shader converter tool.
+ FilePath converter_tool;
};
// Collada Param Names.