blob: 93a0d42e1ab535a8fa02693cd62b30d655dc8c16 [file] [log] [blame]
/*
* Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
* for details. All rights reserved. Use of this source code is governed by a
* BSD-style license that can be found in the LICENSE file.
*/
/**
* @description Test of get calls against GL objects like getBufferParameter,
* etc.
*/
import "dart:html";
import "dart:web_gl" as wgl;
import 'dart:typed_data';
import "../../../testcommon.dart";
import "resources/webgl-test.dart";
import "resources/webgl-test-utils.dart" as wtu;
import "../../../../Utils/async_utils.dart";
import "pwd.dart";
main() {
document.body.setInnerHtml('''
<div id="console"></div>
<div>PASS</div>
''', treeSanitizer: new NullTreeSanitizer());
var gl;
sizeInBytes(type) {
switch (type) {
case wgl.BYTE:
case wgl.UNSIGNED_BYTE:
return 1;
case wgl.SHORT:
case wgl.UNSIGNED_SHORT:
return 2;
case wgl.INT:
case wgl.UNSIGNED_INT:
case wgl.FLOAT:
return 4;
default:
throw "unknown type";
}
}
gl = create3DContext();
var standardVert = loadStandardVertexShader(gl);
var standardFrag = loadStandardFragmentShader(gl);
var standardProgram = gl.createProgram();
gl.attachShader(standardProgram, standardVert);
gl.attachShader(standardProgram, standardFrag);
gl.linkProgram(standardProgram);
var shaders = gl.getAttachedShaders(standardProgram);
shouldBe(shaders.length, 2);
shouldBeTrue(shaders[0] == standardVert && shaders[1] == standardFrag || shaders[1] == standardVert && shaders[0] == standardFrag);
glErrorShouldBe(gl, wgl.NO_ERROR);
shouldBeNull(gl.getAttachedShaders(null));
glErrorShouldBe(gl, wgl.INVALID_VALUE);
shouldThrow(() => gl.getAttachedShaders(standardVert));
glErrorShouldBe(gl, wgl.NO_ERROR);
// Test getBufferParameter
var buffer = gl.createBuffer();
gl.bindBuffer(wgl.ARRAY_BUFFER, buffer);
gl.bufferData(wgl.ARRAY_BUFFER, 16, wgl.DYNAMIC_DRAW);
shouldBe(gl.getBufferParameter(wgl.ARRAY_BUFFER, wgl.BUFFER_SIZE), 16);
shouldBe(gl.getBufferParameter(wgl.ARRAY_BUFFER, wgl.BUFFER_USAGE), wgl.DYNAMIC_DRAW);
// Test getFramebufferAttachmentParameter
var texture = gl.createTexture();
gl.bindTexture(wgl.TEXTURE_2D, texture);
gl.texImage2D(wgl.TEXTURE_2D, 0, wgl.RGBA, 2, 2, 0, wgl.RGBA, wgl.UNSIGNED_BYTE,
new Uint8List.fromList([
0, 0, 0, 255,
255, 255, 255, 255,
255, 255, 255, 255,
0, 0, 0, 255]));
gl.texParameteri(wgl.TEXTURE_2D, wgl.TEXTURE_MIN_FILTER, wgl.LINEAR);
gl.texParameteri(wgl.TEXTURE_2D, wgl.TEXTURE_MAG_FILTER, wgl.LINEAR);
gl.bindTexture(wgl.TEXTURE_2D, null);
var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(wgl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(wgl.FRAMEBUFFER, wgl.COLOR_ATTACHMENT0, wgl.TEXTURE_2D, texture, 0);
var renderbuffer = gl.createRenderbuffer();
glErrorShouldBe(gl, wgl.NO_ERROR);
gl.bindRenderbuffer(wgl.RENDERBUFFER, renderbuffer);
glErrorShouldBe(gl, wgl.NO_ERROR);
gl.renderbufferStorage(wgl.RENDERBUFFER, wgl.DEPTH_COMPONENT16, 2, 2);
glErrorShouldBe(gl, wgl.NO_ERROR);
gl.framebufferRenderbuffer(wgl.FRAMEBUFFER, wgl.DEPTH_ATTACHMENT, wgl.RENDERBUFFER, renderbuffer);
// FIXME: on some machines (in particular the WebKit commit bots) the
// framebuffer status is FRAMEBUFFER_UNSUPPORTED; more investigation
// is needed why this is the case, because the FBO allocated
// internally by the WebKit implementation has almost identical
// parameters to this one. See https://bugs.webkit.org/show_bug.cgi?id=31843.
shouldBe(gl.checkFramebufferStatus(wgl.FRAMEBUFFER), wgl.FRAMEBUFFER_COMPLETE);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.COLOR_ATTACHMENT0, wgl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE), wgl.TEXTURE);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.COLOR_ATTACHMENT0, wgl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME), texture);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.COLOR_ATTACHMENT0, wgl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL), 0);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.COLOR_ATTACHMENT0, wgl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE), 0);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.DEPTH_ATTACHMENT, wgl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE), wgl.RENDERBUFFER);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.DEPTH_ATTACHMENT, wgl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME), renderbuffer);
// Test getProgramParameter
shouldBe(gl.getProgramParameter(standardProgram, wgl.DELETE_STATUS), false);
shouldBe(gl.getProgramParameter(standardProgram, wgl.LINK_STATUS), true);
shouldBeTrue(gl.getProgramParameter(standardProgram, wgl.VALIDATE_STATUS) is bool);
shouldBe(gl.getProgramParameter(standardProgram, wgl.ATTACHED_SHADERS), 2);
shouldBe(gl.getProgramParameter(standardProgram, wgl.ACTIVE_ATTRIBUTES), 2);
shouldBe(gl.getProgramParameter(standardProgram, wgl.ACTIVE_UNIFORMS), 1);
// Test getRenderbufferParameter
shouldBe(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_WIDTH), 2);
shouldBe(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_HEIGHT), 2);
// Note: we can't test the actual value of the internal format since
// the implementation is allowed to change it.
shouldBeNonZero(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_INTERNAL_FORMAT));
shouldBeNonZero(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_DEPTH_SIZE));
var colorbuffer = gl.createRenderbuffer();
glErrorShouldBe(gl, wgl.NO_ERROR);
gl.bindRenderbuffer(wgl.RENDERBUFFER, renderbuffer);
glErrorShouldBe(gl, wgl.NO_ERROR);
gl.renderbufferStorage(wgl.RENDERBUFFER, wgl.RGBA4, 2, 2);
shouldBeNonZero(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_RED_SIZE));
shouldBeNonZero(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_GREEN_SIZE));
shouldBeNonZero(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_BLUE_SIZE));
shouldBeNonZero(gl.getRenderbufferParameter(wgl.RENDERBUFFER, wgl.RENDERBUFFER_ALPHA_SIZE));
// Test getShaderParameter
shouldBe(gl.getShaderParameter(standardVert, wgl.SHADER_TYPE), wgl.VERTEX_SHADER);
shouldBe(gl.getShaderParameter(standardVert, wgl.DELETE_STATUS), false);
shouldBe(gl.getShaderParameter(standardVert, wgl.COMPILE_STATUS), true);
// Test getTexParameter
gl.bindFramebuffer(wgl.FRAMEBUFFER, framebuffer);
gl.bindTexture(wgl.TEXTURE_2D, texture);
gl.texParameteri(wgl.TEXTURE_2D, wgl.TEXTURE_MAG_FILTER, wgl.NEAREST);
gl.texParameteri(wgl.TEXTURE_2D, wgl.TEXTURE_MIN_FILTER, wgl.NEAREST);
gl.texParameteri(wgl.TEXTURE_2D, wgl.TEXTURE_WRAP_S, wgl.CLAMP_TO_EDGE);
gl.texParameteri(wgl.TEXTURE_2D, wgl.TEXTURE_WRAP_T, wgl.CLAMP_TO_EDGE);
shouldBe(gl.getTexParameter(wgl.TEXTURE_2D, wgl.TEXTURE_MAG_FILTER), wgl.NEAREST);
shouldBe(gl.getTexParameter(wgl.TEXTURE_2D, wgl.TEXTURE_MIN_FILTER), wgl.NEAREST);
shouldBe(gl.getTexParameter(wgl.TEXTURE_2D, wgl.TEXTURE_WRAP_S), wgl.CLAMP_TO_EDGE);
shouldBe(gl.getTexParameter(wgl.TEXTURE_2D, wgl.TEXTURE_WRAP_T), wgl.CLAMP_TO_EDGE);
// Test getUniform with all variants of data types
// Boolean uniform variables
var boolProgram = loadProgram(gl, "$root/resources/boolUniformShader.vert", "$root/resources/noopUniformShader.frag");
shouldBe(gl.getProgramParameter(boolProgram, wgl.LINK_STATUS), true);
var bvalLoc = gl.getUniformLocation(boolProgram, "bval");
var bval2Loc = gl.getUniformLocation(boolProgram, "bval2");
var bval3Loc = gl.getUniformLocation(boolProgram, "bval3");
var bval4Loc = gl.getUniformLocation(boolProgram, "bval4");
gl.useProgram(boolProgram);
gl.uniform1i(bvalLoc, 1);
gl.uniform2i(bval2Loc, 1, 0);
gl.uniform3i(bval3Loc, 1, 0, 1);
gl.uniform4i(bval4Loc, 1, 0, 1, 0);
glErrorShouldBe(gl, wgl.NO_ERROR);
shouldBe(gl.getUniform(boolProgram, bvalLoc), true);
shouldBeList(gl.getUniform(boolProgram, bval2Loc), [true, false]);
shouldBeList(gl.getUniform(boolProgram, bval3Loc), [true, false, true]);
shouldBeList(gl.getUniform(boolProgram, bval4Loc), [true, false, true, false]);
// Integer uniform variables
var intProgram = loadProgram(gl, "$root/resources/intUniformShader.vert", "$root/resources/noopUniformShader.frag");
shouldBe(gl.getProgramParameter(intProgram, wgl.LINK_STATUS), true);
var ivalLoc = gl.getUniformLocation(intProgram, "ival");
var ival2Loc = gl.getUniformLocation(intProgram, "ival2");
var ival3Loc = gl.getUniformLocation(intProgram, "ival3");
var ival4Loc = gl.getUniformLocation(intProgram, "ival4");
gl.useProgram(intProgram);
gl.uniform1i(ivalLoc, 1);
gl.uniform2i(ival2Loc, 2, 3);
gl.uniform3i(ival3Loc, 4, 5, 6);
gl.uniform4i(ival4Loc, 7, 8, 9, 10);
glErrorShouldBe(gl, wgl.NO_ERROR);
shouldBe(gl.getUniform(intProgram, ivalLoc), 1);
shouldBeList(gl.getUniform(intProgram, ival2Loc), [2, 3]);
shouldBeList(gl.getUniform(intProgram, ival3Loc), [4, 5, 6]);
shouldBeList(gl.getUniform(intProgram, ival4Loc), [7, 8, 9, 10]);
// Float uniform variables
var floatProgram = loadProgram(gl, "$root/resources/floatUniformShader.vert", "$root/resources/noopUniformShader.frag");
shouldBe(gl.getProgramParameter(floatProgram, wgl.LINK_STATUS), true);
var fvalLoc = gl.getUniformLocation(floatProgram, "fval");
var fval2Loc = gl.getUniformLocation(floatProgram, "fval2");
var fval3Loc = gl.getUniformLocation(floatProgram, "fval3");
var fval4Loc = gl.getUniformLocation(floatProgram, "fval4");
gl.useProgram(floatProgram);
gl.uniform1f(fvalLoc, 11);
gl.uniform2f(fval2Loc, 12, 13);
gl.uniform3f(fval3Loc, 14, 15, 16);
gl.uniform4f(fval4Loc, 17, 18, 19, 20);
glErrorShouldBe(gl, wgl.NO_ERROR);
shouldBe(gl.getUniform(floatProgram, fvalLoc), 11);
shouldBeList(gl.getUniform(floatProgram, fval2Loc), [12, 13]);
shouldBeList(gl.getUniform(floatProgram, fval3Loc), [14, 15, 16]);
shouldBeList(gl.getUniform(floatProgram, fval4Loc), [17, 18, 19, 20]);
// Sampler uniform variables
var samplerProgram = loadProgram(gl, "$root/resources/noopUniformShader.vert", "$root/resources/samplerUniformShader.frag");
shouldBe(gl.getProgramParameter(samplerProgram, wgl.LINK_STATUS), true);
var s2DValLoc = gl.getUniformLocation(samplerProgram, "s2D");
var sCubeValLoc = gl.getUniformLocation(samplerProgram, "sCube");
gl.useProgram(samplerProgram);
gl.uniform1i(s2DValLoc, 0);
gl.uniform1i(sCubeValLoc, 1);
glErrorShouldBe(gl, wgl.NO_ERROR);
shouldBe(gl.getUniform(samplerProgram, s2DValLoc), 0);
shouldBe(gl.getUniform(samplerProgram, sCubeValLoc), 1);
// Matrix uniform variables
var matProgram = loadProgram(gl, "$root/resources/matUniformShader.vert", "$root/resources/noopUniformShader.frag");
shouldBe(gl.getProgramParameter(matProgram, wgl.LINK_STATUS), true);
var mval2Loc = gl.getUniformLocation(matProgram, "mval2");
var mval3Loc = gl.getUniformLocation(matProgram, "mval3");
var mval4Loc = gl.getUniformLocation(matProgram, "mval4");
gl.useProgram(matProgram);
gl.uniformMatrix2fv(mval2Loc, false, new Float32List.fromList([1.0, 2.0, 3.0, 4.0]));
gl.uniformMatrix3fv(mval3Loc, false, new Float32List.fromList([5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0]));
gl.uniformMatrix4fv(mval4Loc, false, new Float32List.fromList([14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0]));
glErrorShouldBe(gl, wgl.NO_ERROR);
shouldBeList(gl.getUniform(matProgram, mval2Loc), [1, 2, 3, 4]);
shouldBeList(gl.getUniform(matProgram, mval3Loc), [5, 6, 7, 8, 9, 10, 11, 12, 13]);
shouldBeList(gl.getUniform(matProgram, mval4Loc), [14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]);
// Test getVertexAttrib
var array = new Float32List.fromList([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0]);
gl.bindBuffer(wgl.ARRAY_BUFFER, buffer);
gl.bufferData(wgl.ARRAY_BUFFER, array, wgl.DYNAMIC_DRAW);
// Vertex attribute 0 is special in that it has no current state, so
// fetching GL_CURRENT_VERTEX_ATTRIB generates an error. Use attribute
// 1 for these tests instead.
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 4, wgl.FLOAT, false, 0, 0);
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING), buffer);
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_ENABLED), true);
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_SIZE), 4);
// Stride MUST be the value the user put in.
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_STRIDE), 0);
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_TYPE), wgl.FLOAT);
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_NORMALIZED), false);
gl.vertexAttribPointer(1, 4, wgl.FLOAT, false, 36, 12);
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_STRIDE), 36);
shouldBe(gl.getVertexAttribOffset(1, wgl.VERTEX_ATTRIB_ARRAY_POINTER), 12);
gl.disableVertexAttribArray(1);
shouldBe(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_ENABLED), false);
gl.vertexAttrib4f(1, 5, 6, 7, 8);
shouldBeList(gl.getVertexAttrib(1, wgl.CURRENT_VERTEX_ATTRIB), [5, 6, 7, 8]);
glErrorShouldBe(gl, wgl.NO_ERROR);
// Test cases where name == 0
gl.deleteTexture(texture);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.COLOR_ATTACHMENT0, wgl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE), wgl.NONE);
gl.deleteRenderbuffer(renderbuffer);
shouldBe(gl.getFramebufferAttachmentParameter(wgl.FRAMEBUFFER, wgl.DEPTH_ATTACHMENT, wgl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE), wgl.NONE);
gl.deleteBuffer(buffer);
shouldBeNull(gl.getVertexAttrib(1, wgl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING));
glErrorShouldBe(gl, wgl.NO_ERROR);
}