2 * Copyright 2009, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // This file defines platform-specific implementations of certain
34 // methods of ColladaConditioner.
36 #include "import/cross/precompile.h"
38 #include <d3dx9effect.h>
40 #include "base/base_paths.h"
41 #include "base/file_path.h"
42 #include "base/path_service.h"
43 #include "core/cross/error.h"
44 #include "core/cross/service_locator.h"
45 #include "import/cross/collada.h"
46 #include "import/cross/collada_conditioner.h"
50 const int kTimeoutInSeconds
= 30;
52 bool ColladaConditioner::CompileHLSL(const String
& shader_source
,
53 const String
& vs_entry
,
54 const String
& ps_entry
) {
56 String shader_source_hlsl
= shader_source
;
60 " VertexShader = compile vs_2_0 " + vs_entry
+ "();\n"
61 " PixelShader = compile ps_2_0 " + ps_entry
+ "();\n"
65 // Create an effect compiler from the FX file.
66 ID3DXEffectCompiler
* compiler
= NULL
;
67 ID3DXBuffer
* parse_errors
= NULL
;
68 HRESULT hr
= ::D3DXCreateEffectCompiler(shader_source_hlsl
.c_str(),
70 shader_source_hlsl
.size()),
78 const char* error_str
= reinterpret_cast<const char*>(
79 parse_errors
->GetBufferPointer());
80 O3D_ERROR(service_locator_
) << error_str
;
82 ID3DXBuffer
* effect_buffer
;
83 ID3DXBuffer
* error_buffer
;
84 hr
= compiler
->CompileEffect(0, &effect_buffer
, &error_buffer
);
86 const char* compile_errors
= reinterpret_cast<const char*>(
87 error_buffer
->GetBufferPointer());
88 O3D_ERROR(service_locator_
) << compile_errors
;
91 if (effect_buffer
) effect_buffer
->Release();
92 if (error_buffer
) error_buffer
->Release();
94 if (compiler
) compiler
->Release();
95 if (parse_errors
) parse_errors
->Release();
100 // Find cgc executable, and run it on the input so that we can get a
101 // preprocessed version out.
102 bool ColladaConditioner::PreprocessShaderFile(const FilePath
& in_filename
,
103 const FilePath
& out_filename
) {
104 FilePath executable_path
;
105 if (!PathService::Get(base::DIR_EXE
, &executable_path
)) {
106 O3D_ERROR(service_locator_
) << "Couldn't get executable path.";
109 executable_path
= executable_path
.Append(FILE_PATH_LITERAL("cgc.exe"));
111 cmd
= L
"\"" + executable_path
.value() + L
"\" ";
112 cmd
+= L
"-E \"" + in_filename
.value() + L
"\" ";
113 cmd
+= L
"-o \"" + out_filename
.value() + L
"\"";
115 // Have to dup the string because CreateProcessW might modify the
117 wchar_t* buf
= ::_wcsdup(cmd
.c_str());
119 // Initialize structure to zero with default array initializer.
120 PROCESS_INFORMATION process_info
= {0};
121 // Initialize structure to it's size, followed by zeros.
122 STARTUPINFO startup_info
= {sizeof(STARTUPINFO
)};
124 BOOL success
= ::CreateProcessW(NULL
,
137 int exit_code
= ::WaitForSingleObject(process_info
.hProcess
,
138 kTimeoutInSeconds
* 1000);
139 if (exit_code
== WAIT_OBJECT_0
) {
141 } else if (exit_code
== WAIT_TIMEOUT
) {
142 O3D_ERROR(service_locator_
) << "Timed out waiting for cg compiler!";
144 O3D_ERROR(service_locator_
) << "Couldn't start cg compiler (cgc.exe).";
147 O3D_ERROR(service_locator_
) << "Couldn't start cg compiler (cgc.exe).";
149 ::CloseHandle(process_info
.hProcess
);
150 ::CloseHandle(process_info
.hThread
);
152 return success
== TRUE
;
154 } // end namespace o3d