1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6 <title>WebGL Program Compiling/Linking Conformance Test</title>
7 <link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
8 <script src="../../js/resources/js-test-pre.js" type="text/javascript"></script>
9 <script src="resources/webgl-test.js" type="text/javascript"></script>
12 <div id="description"></div>
13 <div id="console"></div>
14 <canvas id="canvas" width="2" height="2"> </canvas>
15 <script type="text/javascript">
17 description("Tests that program compiling/linking/using works correctly.");
20 debug("Canvas.getContext");
22 var gl = create3DContext(document.getElementById("canvas"));
24 testFailed("context does not exist");
28 testPassed("context exists");
30 gl.clearColor(0.0, 0.0, 0.0, 0.0);
31 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
34 /////// Check compileShader() /////////////////////////////
36 var vs = gl.createShader(gl.VERTEX_SHADER);
37 gl.shaderSource(vs, "attribute vec4 aVertex; attribute vec4 aColor; varying vec4 vColor; void main() { vColor = aColor; gl_Position = aVertex; }");
40 assertMsg(gl.getShaderParameter(vs, gl.COMPILE_STATUS) == true,
41 "good vertex shader should compile");
43 var vs2 = gl.createShader(gl.VERTEX_SHADER);
44 gl.shaderSource(vs2, "attribute vec4 aVertex; attribute vec4 aColor; varying vec4 vColor; void main() { vColor = aColor; gl_Position = aVertex * 0.5; }");
45 gl.compileShader(vs2);
47 assertMsg(gl.getShaderParameter(vs2, gl.COMPILE_STATUS) == true,
48 "good vertex shader #2 should compile");
50 var vsBad = gl.createShader(gl.VERTEX_SHADER);
51 gl.shaderSource(vsBad, "WILL NOT COMPILE;");
52 gl.compileShader(vsBad);
54 assertMsg(gl.getShaderParameter(vsBad, gl.COMPILE_STATUS) == false,
55 "bad vertex shader should fail to compile");
57 var fs = gl.createShader(gl.FRAGMENT_SHADER);
58 gl.shaderSource(fs, "#ifdef GL_ES\nprecision mediump float;\n#endif\n varying vec4 vColor; void main() { gl_FragColor = vColor; }");
61 assertMsg(gl.getShaderParameter(fs, gl.COMPILE_STATUS) == true,
62 "good fragment shader should compile");
64 var fs2 = gl.createShader(gl.FRAGMENT_SHADER);
65 gl.shaderSource(fs2, "#ifdef GL_ES\nprecision mediump float;\n#endif\n varying vec4 vColor; void main() { gl_FragColor = vColor * 0.5; }");
66 gl.compileShader(fs2);
68 assertMsg(gl.getShaderParameter(fs2, gl.COMPILE_STATUS) == true,
69 "good fragment shader #2 should compile");
71 var fsBad = gl.createShader(gl.FRAGMENT_SHADER);
72 gl.shaderSource(fsBad, "WILL NOT COMPILE;");
73 gl.compileShader(fsBad);
75 assertMsg(gl.getShaderParameter(fsBad, gl.COMPILE_STATUS) == false,
76 "bad fragment shader should fail to compile");
78 assertMsg(gl.getError() == gl.NO_ERROR,
79 "should be no errors at this point");
81 /////// Check attachShader() /////////////////////////////
83 function checkAttachShader(already_attached_shaders, shader, expected_error_code, errmsg) {
84 var prog = gl.createProgram();
85 for (var i = 0; i < already_attached_shaders.length; ++i)
86 gl.attachShader(prog, already_attached_shaders[i]);
87 if(gl.getError() != gl.NO_ERROR)
88 assertMsg(false, "unexpected error in attachShader()");
89 gl.attachShader(prog, shader);
90 assertMsg(gl.getError() == expected_error_code, errmsg);
93 checkAttachShader([], vs, gl.NO_ERROR, "attaching a vertex shader should succeed");
94 checkAttachShader([vs], vs, gl.INVALID_OPERATION,
95 "attaching an already attached vertex shader should generate INVALID_OPERATION");
96 checkAttachShader([], fs, gl.NO_ERROR, "attaching a fragment shader should succeed");
97 checkAttachShader([fs], fs, gl.INVALID_OPERATION,
98 "attaching an already attached fragment shader should generate INVALID_OPERATION");
100 /////// Check detachShader() /////////////////////////////
102 function checkDetachShader(already_attached_shaders, shader, expected_error_code, errmsg) {
103 var prog = gl.createProgram();
104 for (var i = 0; i < already_attached_shaders.length; ++i)
105 gl.attachShader(prog, already_attached_shaders[i]);
106 if(gl.getError() != gl.NO_ERROR)
107 assertMsg(false, "unexpected error in attachShader()");
108 gl.detachShader(prog, shader);
109 assertMsg(gl.getError() == expected_error_code, errmsg);
112 checkDetachShader([vs], vs, gl.NO_ERROR, "detaching a vertex shader should succeed");
113 checkDetachShader([fs], vs, gl.INVALID_OPERATION,
114 "detaching a not already attached vertex shader should generate INVALID_OPERATION");
115 checkDetachShader([fs], fs, gl.NO_ERROR, "detaching a fragment shader should succeed");
116 checkDetachShader([vs], fs, gl.INVALID_OPERATION,
117 "detaching a not already attached fragment shader should generate INVALID_OPERATION");
119 /////// Check getAttachedShaders() /////////////////////////////
121 function checkGetAttachedShaders(shaders_to_attach, shaders_to_detach, expected_shaders, errmsg) {
122 var prog = gl.createProgram();
123 for (var i = 0; i < shaders_to_attach.length; ++i)
124 gl.attachShader(prog, shaders_to_attach[i]);
125 if(gl.getError() != gl.NO_ERROR)
126 assertMsg(false, "unexpected error in attachShader()");
127 for (var i = 0; i < shaders_to_detach.length; ++i)
128 gl.detachShader(prog, shaders_to_detach[i]);
129 if(gl.getError() != gl.NO_ERROR)
130 assertMsg(false, "unexpected error in detachShader()");
131 assertMsg(areArraysEqual(gl.getAttachedShaders(prog), expected_shaders), errmsg);
133 checkGetAttachedShaders([], [], [], "getAttachedShaders should return an empty list by default");
134 checkGetAttachedShaders([fs], [], [fs], "attaching a single shader should give the expected list");
135 checkGetAttachedShaders([fs, vs, fs2, vs2], [], [fs, vs, fs2, vs2],
136 "attaching some shaders should give the expected list");
137 checkGetAttachedShaders([fs], [fs], [], "attaching a shader and detaching it shoud leave an empty list");
138 checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs, fs2, vs2], [],
139 "attaching some shaders and detaching them in same order shoud leave an empty list");
140 checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2, vs, fs2], [],
141 "attaching some shaders and detaching them in random order shoud leave an empty list");
142 checkGetAttachedShaders([fs, vs, fs2, vs2], [vs], [fs, fs2, vs2],
143 "attaching and detaching some shaders should leave the difference list");
144 checkGetAttachedShaders([fs, vs, fs2, vs2], [fs, vs2], [vs, fs2],
145 "attaching and detaching some shaders should leave the difference list");
146 checkGetAttachedShaders([fsBad], [], [fsBad],
147 "attaching a shader that failed to compile should still show it in the list");
148 checkGetAttachedShaders([fs, vsBad, fs2], [], [fs, vsBad, fs2],
149 "attaching shaders, including one that failed to compile, should still show the it in the list");
151 /////// Check linkProgram() and useProgram /////////////////////////////
153 function checkLinkAndUse(shaders, expected_status, errmsg) {
154 var prog = gl.createProgram();
155 for (var i = 0; i < shaders.length; ++i)
156 gl.attachShader(prog, shaders[i]);
157 gl.bindAttribLocation(prog, 0, "aVertex");
158 gl.bindAttribLocation(prog, 1, "aColor");
159 gl.linkProgram(prog);
160 if (gl.getError() != gl.NO_ERROR)
161 assertMsg(false, "unexpected error in linkProgram()");
162 assertMsg(gl.getProgramParameter(prog, gl.LINK_STATUS) == expected_status, errmsg);
163 if (expected_status == true && gl.getProgramParameter(prog, gl.LINK_STATUS) == false)
164 debug(gl.getProgramInfoLog(prog));
165 if (gl.getError() != gl.NO_ERROR)
166 assertMsg(false, "unexpected error in getProgramParameter()");
168 if (expected_status == true)
169 assertMsg(gl.getError() == gl.NO_ERROR, "using a valid program should succeed");
170 if (expected_status == false)
171 assertMsg(gl.getError() == gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
175 var progGood1 = checkLinkAndUse([vs, fs], true, "valid program should link");
176 var progGood2 = checkLinkAndUse([vs, fs2], true, "valid program #2 should link");
177 var progBad1 = checkLinkAndUse([vs], false, "program with no fragment shader should fail to link");
178 var progBad2 = checkLinkAndUse([fs], false, "program with no vertex shader should fail to link");
179 var progBad3 = checkLinkAndUse([vsBad, fs], false, "program with bad vertex shader should fail to link");
180 var progBad4 = checkLinkAndUse([vs, fsBad], false, "program with bad fragment shader should fail to link");
181 var progBad5 = checkLinkAndUse([vsBad, fsBad], false, "program with bad shaders should fail to link");
183 gl.useProgram(progGood1);
184 assertMsg(gl.getError() == gl.NO_ERROR,
185 "using a valid program shouldn't generate a GL error");
187 var vbuf = gl.createBuffer();
188 gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
189 gl.bufferData(gl.ARRAY_BUFFER,
194 0.0, 1.0, 0.0, 1.0]),
196 gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
197 gl.enableVertexAttribArray(0);
198 gl.vertexAttrib3f(1, 1.0, 0.0, 0.0);
200 assertMsg(gl.getError() == gl.NO_ERROR,
201 "should be no errors at this point #2");
203 gl.useProgram(progGood1);
204 gl.drawArrays(gl.TRIANGLES, 0, 3);
205 assertMsg(gl.getError() == gl.NO_ERROR,
206 "drawing with a valid program shouldn't generate a GL error");
208 gl.useProgram(progBad1);
209 assertMsg(gl.getError() == gl.INVALID_OPERATION,
210 "using an invalid program should generate INVALID_OPERATION");
211 gl.drawArrays(gl.TRIANGLES, 0, 3);
212 assertMsg(gl.getError() != gl.NO_ERROR,
213 "drawing with an invalid program should generate some GL error XXX");
215 gl.useProgram(progGood2);
216 gl.attachShader(progGood2, fsBad);
217 gl.linkProgram(progGood2);
218 assertMsg(gl.getProgramParameter(progGood2, gl.LINK_STATUS) == false,
219 "linking should fail with in-use formerly good program, with new bad shader attached");
221 gl.useProgram(progGood1);
222 gl.drawArrays(gl.TRIANGLES, 0, 4);
223 assertMsg(gl.getError() == gl.NO_ERROR,
224 "drawing with a valid when last used program shouldn't generate a GL error");
228 successfullyParsed = true;
232 <script src="../../js/resources/js-test-post.js"></script>