如何在 <script> 应答器中读取文件
How to read a file in a <script> balise
长期以来,我经常在一个问题上伤害自己:我是 运行 一个使用着色器代码的 WebGL api。这些着色器存储在我的 html 页面头部的应答器中,如下所示:
<script id="vertex-shader" type="x-shader/x-vertex">
[vertex shader code here...]
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
[fragment shader code here...]
</script>
但我不喜欢将我的 GLSL 代码直接放在我的 html 页面中。所以我想让以下内容起作用:
<script id="vertex-shader" type="x-shader/x-vertex" src="path/to/shader/file.vert"></script>
<script id="fragment-shader" type="x-shader/x-fragment" src="path/to/shader/file.frag"></script>
并为每个着色器提供他自己的文件,只有他在 html 脚本应答器中的路径。
但是,我如何在我的页面加载后从 javascript 代码访问该文件?我知道我将不得不使用 FileReader
对象来读取它,我知道如何使用它,但我不知道如何到达与我的着色器源文件对应的 File
对象,即使当我得到了字符串中的完整路径。
我不想发出 Ajax 请求,因为我不想在我的页面加载后在服务器上发出任何更多请求。
请告诉我如何从他的路径打开文件...或者如果我在这里尝试做的事情是不可能的。
最简单的方法是向文件发出 AJAX GET HTTP 请求:
function getShader(id){
return new Promise(function(resolve, reject){ // return a future
var script = document.getElementById(id).src;
var xhr = new XMLHttpRequest;
xhr.onload = function(){ resolve(xhr.responseText); };
xhr.onerror = reject;
xhr.open("GET", script);
xhr.send();
});
}
这反过来会让你做:
getShader("vertex-shader").then(function(content){
// content is the contents of the file.
});
您也可以遍历 DOM 并将所有着色器类似地放在贴图中:
function loadAllShaders(){
var shaders = document.querySelectorAll('[type="x-shader/x-vertex"]');
var futures = [], names = [];
for(var i = 0; i < shaders.length; i++){
futures.push(getShader(shaders[i].id));
names.push(shaders[i].id);
}
return Promise.all(shaders).then(function(results){
var obj = {};
names.forEach(function(name, i){
obj[name] = results[i];
});
return obj;
});
}
哪个会让你做:
loadAllShaders().then(function(map){
map["fragment-shader"]; // contains the content of the shader
});
长期以来,我经常在一个问题上伤害自己:我是 运行 一个使用着色器代码的 WebGL api。这些着色器存储在我的 html 页面头部的应答器中,如下所示:
<script id="vertex-shader" type="x-shader/x-vertex">
[vertex shader code here...]
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
[fragment shader code here...]
</script>
但我不喜欢将我的 GLSL 代码直接放在我的 html 页面中。所以我想让以下内容起作用:
<script id="vertex-shader" type="x-shader/x-vertex" src="path/to/shader/file.vert"></script>
<script id="fragment-shader" type="x-shader/x-fragment" src="path/to/shader/file.frag"></script>
并为每个着色器提供他自己的文件,只有他在 html 脚本应答器中的路径。
但是,我如何在我的页面加载后从 javascript 代码访问该文件?我知道我将不得不使用 FileReader
对象来读取它,我知道如何使用它,但我不知道如何到达与我的着色器源文件对应的 File
对象,即使当我得到了字符串中的完整路径。
我不想发出 Ajax 请求,因为我不想在我的页面加载后在服务器上发出任何更多请求。
请告诉我如何从他的路径打开文件...或者如果我在这里尝试做的事情是不可能的。
最简单的方法是向文件发出 AJAX GET HTTP 请求:
function getShader(id){
return new Promise(function(resolve, reject){ // return a future
var script = document.getElementById(id).src;
var xhr = new XMLHttpRequest;
xhr.onload = function(){ resolve(xhr.responseText); };
xhr.onerror = reject;
xhr.open("GET", script);
xhr.send();
});
}
这反过来会让你做:
getShader("vertex-shader").then(function(content){
// content is the contents of the file.
});
您也可以遍历 DOM 并将所有着色器类似地放在贴图中:
function loadAllShaders(){
var shaders = document.querySelectorAll('[type="x-shader/x-vertex"]');
var futures = [], names = [];
for(var i = 0; i < shaders.length; i++){
futures.push(getShader(shaders[i].id));
names.push(shaders[i].id);
}
return Promise.all(shaders).then(function(results){
var obj = {};
names.forEach(function(name, i){
obj[name] = results[i];
});
return obj;
});
}
哪个会让你做:
loadAllShaders().then(function(map){
map["fragment-shader"]; // contains the content of the shader
});