Vous êtes sur la page 1sur 4

ng 2-3.

Loading shaders with the XMLHttpRequestObject


//get shader sources with XMLHttpRequestObject
var
fs_source = null,
vs_source = null;
var xhr = new XMLHttpRequest();
//synchronous request requires a false third parameter
xhr.open('GET', './shader.vs', false);
//overriding the mime type is required
xhr.overrideMimeType('text/xml');
xhr.send(null);
if (xhr.readyState == xhr.DONE) {
if(xhr.status === 200)
{
vs_source = xhr.responseXML.documentElement.firstChild.data;
} else {
console. error("Error: " + xhr.statusText);
}
}
xhr.open('GET', './shader.fs', false);
xhr.send(null);
if (xhr.readyState == xhr.DONE) {
if(xhr.status === 200)
{
fs_source = xhr.responseXML.documentElement.firstChild.data;
} else {
console. error("Error: " + xhr.statusText);
}
}
In Listing 2-3 we are sending synchronous requests. Alternatively, we could use asynchronous calls
and
callback functions to signal that we are ready to move on with our program. In Listing 2-3 we also
have to
override the mime type to XML because the browser may not otherwise recognize the content of
our shaders as
a XML document. When the readyState is equal to XMLHttpRequestObject.DONE, then we check
the status.
A status of 200 means success and we can grab the data we need from the responseXML object:
responseXML.
documentElement.firstChild.data. If the status is not 200, we output an error message to the
console.
Starting with a copy of the 01/3D_triangles_depth_test.html file that was the last example of
Chapter 1,
remove the inline shader scripts at the top of the file and swap out these lines with those found in
Listing 2-3:
//get shader source
var fs_source = document.getElementById('shader-fs').innerHTML,
vs_source = document.getElementById('shader-vs').innerHTML;
When you run the modified application, you will see that it works exactly the same as before. This
can be
found in the 02/vanilla_ajax.html file.
N Note Remember that you must be running a web server to use this approach. In Figure 2-3, I
naively try run-
ning my file directly in the browser. You can see in the Chrome developer tools console the error
that this causes.
Developer and debugging tools are very useful and are covered in depth in Chapter 9.
40CHAPTER 2 N SHADERS 101
Figure 2-3. Error caused by trying to load an external file without a web server
Using jQuery
If we use a higher-level JavaScript API such as the very popular jQuery, there are a couple of
advantages. First,
it is easier because some of the low-level code is obscured for us. Second, it is more cross-browser
compatible.
A quick background of jQuery can be found in Appendix A. The equivalent jQuery functionality of
Listing 2-3 is
shown in Listing 2-4:
Listing 2-4. Loading shaders with jQuery
//get shader sources with jQuery Ajax
$.ajax({
async: false,
url: './shader.vs',
success: function (data) {
vs_source = data.firstChild.textContent;
},
dataType: 'xml'
});
$.ajax({
async: false,
url: './shader.fs',
success: function (data) {
fs_source = data.firstChild.textContent;
},
dataType: 'xml'
});
Because jQuery extracts away the underlying XHR calls and the $.ajax method explicitly states the
parameters that it is using, Listing 2-4 is both more concise and easier to understand than Listing 2-
3.
Remember to also include a link to the jQuery library. The latest version of the jQuery library
hosted on the
jQuery CDN is available for development usage from http://code.jquery.com/jquery-latest.js and for
production
usage, the minified form can be found at http://code.jquery.com/jquery-latest.min.js. The full source
code for
this example is available on the books companion sites and is available in the file
02/jquery_ajax.html. There is
an issue associated with including the full shader source, including script tags, externally and then
parsing. The
issue and solution are discussed in Chapter 9.
41CHAPTER 2 N SHADERS 101
GLSL Specification in More Detail
Earlier, I mentioned that the GLSL is similar to C++. It uses a subset of ASCII characters and
carriage return and/
or line feeds to terminate each line. The language is case sensitive and it is interesting to note that
unlike C/C++,
there are no character or string types used. As such, there are also no characters used for quoting.
Variable and
function names must start with an alphabet character or underscore, but cannot start with gl_ or be a
reserved
language word. Each shader program can have only one main method, which is the same as C/C++.
Primitive Types
The available basic types that are inherited from C++ are shown in Table 2-1.
Table 2-1. C++ Inherited Types and Descriptions
C++ types Description
void Used to specify a function with no return value and/or no
parameters
bool Boolean true or false
int Signed integers. Example: 1, 7, 13
float Floating point number. Example: 1.3, 7.0, 13.445
GLSL defines new primitive types that are shown in Table 2-2.
Table 2-2. GLSL Types and Descriptions
GLSL types Description
vec2, vec3, vec4, ivec2, ivec3, vec4, bvec2,
bvec3, bvec4 Vector of size 1×2, 1x3, or 1x4; and of type float, integer,
or bool, respectively
mat2, mat3, mat4 Floating point matrix of size 2x2, 3x3, or 4x4
sampler2D, samplerCube Handles to 2D or cube mapped textures
We can also create structures that can hold more complex composite types. For instance:
struct myStruct{
vec3 something;
mat4 somethingElse;
}
Qualifiers
GLSL has several optional qualifiers for variables. These fall into the categories of storage,
parameter, precision
and invariant qualifiers.
Storage Qualifiers
Storage qualifiers describe both the variable scope and relation to the WebGL program.
42CHAPTER 2 N SHADERS 101
A variable might be declared with attribute storage as attribute vec3 aColor;.
Table 2-3. Storage Qualifiers
Qualifier Description
[none] The default for a variable is to have no storage qualifier. Local variables and function input
parameters have no storage qualifiers.
const Constant throughout the program. Read only.
uniform Constant value across an entire primitive.
attribute VS per vertex information from our WebGL application.
varying VS write, FS read.
N Note Prefixes are not required, but are commonly used to help represent the storage type of
variables to other
programmers: v for varying, u for uniform, and a for attribute. For example:
attribute vec3 aVertexNormals;
uniform uSampler;
varying vOriginalPosition;
Parameter Qualifiers
Parameter qualifiers are used for function parameters (see Table 2-4).
A function in WebGL might look like this:
vec3 a = (0, 1, 0);
vec3 c;
void myFunction(a, out c){
c = a * 2;
}
Table 2-4. Parameter Qualifiers
Qualifier Description
[none] The default, which is the same thing as specifying the in qualifier
In Parameters passed into a function
Out Parameters to be passed out of a function, but were not initialized
Inout Initialized parameter that will also be passed out of a function
Precision Qualifiers
There are three different precision qualifiers for the GLSL: highp, mediump, and lowp. highp
satisfies the
minimum requirements for the vertex language. mediump satisfies the minimum precision for the
FS. lowp is less
than medium but still fully represents the values of a color channel.
43CHAPTER 2 N SHADERS 101
Invariant Qualifier
Lastly, there is the invariant qualifier

Vous aimerez peut-être aussi