如何在<script> balise </script>中读取文件

时间:2015-04-11 22:59:31

标签: javascript webgl

我经常长时间在一个问题上伤害自己:我正在运行使用着色器代码的WebGL api。这些着色器存储在我的html页面头部的balise中,如下所示:

<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>

但我不想直接在我的html页面中使用我的GLSL代码。所以我想让以下工作:

<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脚本balise中使用它。

但是,如果我的页面加载后如何从javascript代码中获取文件?我知道我必须使用FileReader对象来阅读它,我知道如何使用它,但我不知道如何到达与我的着色器相对应的File个对象。 s源文件,即使我在字符串中获得完整路径。

我不想发表Ajax请求,因为我的页面加载后我不想再在服务器上发出任何请求。

请告诉我如何从他的路径打开文件...或者如果我在这里尝试做的事情是不可能的。

1 个答案:

答案 0 :(得分:1)

最简单的方法是向文件发出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
});