DSDSWeb/static/js/Cesium-1.53/Specs/Renderer/DrawSpec.js

1379 lines
45 KiB
JavaScript

defineSuite([
'Core/BoundingRectangle',
'Core/Color',
'Core/ComponentDatatype',
'Core/IndexDatatype',
'Core/PrimitiveType',
'Core/WebGLConstants',
'Core/WindingOrder',
'Renderer/Buffer',
'Renderer/BufferUsage',
'Renderer/ClearCommand',
'Renderer/ContextLimits',
'Renderer/DrawCommand',
'Renderer/RenderState',
'Renderer/ShaderProgram',
'Renderer/VertexArray',
'Scene/BlendingState',
'Specs/createContext'
], 'Renderer/Draw', function(
BoundingRectangle,
Color,
ComponentDatatype,
IndexDatatype,
PrimitiveType,
WebGLConstants,
WindingOrder,
Buffer,
BufferUsage,
ClearCommand,
ContextLimits,
DrawCommand,
RenderState,
ShaderProgram,
VertexArray,
BlendingState,
createContext) {
'use strict';
var context;
var sp;
var va;
beforeAll(function() {
context = createContext();
});
afterAll(function() {
context.destroyForSpecs();
});
afterEach(function() {
sp = sp && sp.destroy();
va = va && va.destroy();
});
it('draws a white point', function() {
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
expect({
context : context,
fragmentShader : fs
}).contextToRender();
});
it('draws a white point with an index buffer', function() {
// Use separate context to work around IE 11.0.9 bug
var context = createContext();
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
// Two indices instead of one is a workaround for NVIDIA:
// http://www.khronos.org/message_boards/viewtopic.php?f=44&t=3719
var indexBuffer = Buffer.createIndexBuffer({
context : context,
typedArray : new Uint16Array([0, 0]),
usage : BufferUsage.STATIC_DRAW,
indexDatatype : IndexDatatype.UNSIGNED_SHORT
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}],
indexBuffer : indexBuffer
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
sp = sp.destroy();
va = va.destroy();
context.destroyForSpecs();
});
it('draws a red point with two vertex buffers', function() {
var vs =
'attribute vec4 position;' +
'attribute mediump float intensity;' +
'varying mediump float fs_intensity;' +
'void main() {' +
' gl_PointSize = 1.0; ' +
' gl_Position = position;' +
' fs_intensity = intensity;' +
'}';
var fs = 'varying mediump float fs_intensity; void main() { gl_FragColor = vec4(fs_intensity, 0.0, 0.0, 1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0,
intensity : 1
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}, {
index : 1,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 1
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va
});
command.execute(context);
expect(context).toReadPixels([255, 0, 0, 255]);
});
it('draws a red point with one interleaved vertex buffers', function() {
var vs =
'attribute vec4 position;' +
'attribute mediump float intensity;' +
'varying mediump float fs_intensity;' +
'void main() {' +
' gl_PointSize = 1.0; ' +
' gl_Position = position;' +
' fs_intensity = intensity;' +
'}';
var fs = 'varying mediump float fs_intensity; void main() { gl_FragColor = vec4(fs_intensity, 0.0, 0.0, 1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0,
intensity : 1
}
});
var stride = 5 * Float32Array.BYTES_PER_ELEMENT;
var vertexBuffer = Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1, 1]),
usage : BufferUsage.STATIC_DRAW
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : vertexBuffer,
componentsPerAttribute : 4,
offsetInBytes : 0,
strideInBytes : stride
}, {
index : 1,
vertexBuffer : vertexBuffer,
componentsPerAttribute : 1,
offsetInBytes : 4 * Float32Array.BYTES_PER_ELEMENT,
strideInBytes : stride
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va
});
command.execute(context);
expect(context).toReadPixels([255, 0, 0, 255]);
});
it('draws with scissor test', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
// 1 of 3: Clear to black
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 2 of 3: Render point - fails scissor test
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
scissorTest : {
enabled : true,
rectangle : new BoundingRectangle(1, 1, 0, 0)
}
})
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 3 of 3: Render point - passes scissor test
command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
scissorTest : {
enabled : true,
rectangle : new BoundingRectangle(0, 0, 1, 1)
}
})
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws with color mask', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
// 1 of 3: Clear to black
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 2 of 3: Render point - blue color mask
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
colorMask : {
red : true,
green : false,
blue : false,
alpha : false
}
})
});
command.execute(context);
expect(context).toReadPixels([255, 0, 0, 255]);
// 3 of 3: Render point - red color mask (blue channel not touched)
command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
colorMask : {
red : false,
green : false,
blue : true,
alpha : false
}
})
});
command.execute(context);
expect(context).toReadPixels([255, 0, 255, 255]);
});
it('draws with additive blending', function() {
var cxt = createContext({
webgl : {
alpha : true
}
});
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(0.5); }';
var sp = ShaderProgram.fromCache({
context : cxt,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
var va = new VertexArray({
context : cxt,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : cxt,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
// 1 of 3: Clear to black
ClearCommand.ALL.execute(cxt);
expect(cxt).toReadPixels([0, 0, 0, 0]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
blending : {
enabled : true,
equationRgb : WebGLConstants.FUNC_ADD, // Optional, default
equationAlpha : WebGLConstants.FUNC_ADD, // Optional, default
functionSourceRgb : WebGLConstants.ONE, // Optional, default
functionSourceAlpha : WebGLConstants.ONE, // Optional, default
functionDestinationRgb : WebGLConstants.ONE,
functionDestinationAlpha : WebGLConstants.ONE
}
})
});
// 2 of 3: Blend: 0 + 0.5
command.execute(cxt);
expect({
context : cxt,
epsilon : 1
}).toReadPixels([127, 127, 127, 127]);
// 3 of 3: Blend: 0.5 + 0.5
command.execute(cxt);
expect({
context : cxt,
epsilon : 1
}).toReadPixels([254, 254, 254, 254]);
sp.destroy();
va.destroy();
cxt.destroyForSpecs();
});
it('draws with alpha blending', function() {
var cxt = createContext({
webgl : {
alpha : true
}
});
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 0.5); }';
var sp = ShaderProgram.fromCache({
context : cxt,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
var va = new VertexArray({
context : cxt,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : cxt,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
// 1 of 3: Clear to black
ClearCommand.ALL.execute(cxt);
expect(cxt).toReadPixels([0, 0, 0, 0]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
blending : {
enabled : true,
equationRgb : WebGLConstants.FUNC_ADD,
equationAlpha : WebGLConstants.FUNC_SUBTRACT, // does not actually matter
functionSourceRgb : WebGLConstants.SRC_ALPHA,
functionSourceAlpha : WebGLConstants.ONE, // Don't blend alpha
functionDestinationRgb : WebGLConstants.ONE_MINUS_SRC_ALPHA,
functionDestinationAlpha : WebGLConstants.ZERO
}
})
});
// 2 of 3: Blend: RGB: (255 * 0.5) + (0 * 0.5), Alpha: 0.5 + 0
command.execute(cxt);
expect({
context : cxt,
epsilon : 1
}).toReadPixels([127, 127, 127, 127]);
// 3 of 3: Blend: RGB: (255 * 0.5) + (127 * 0.5), Alpha: 0.5 + 0
command.execute(cxt);
expect({
context : cxt,
epsilon : 2
}).toReadPixels([191, 191, 191, 127]);
sp.destroy();
va.destroy();
cxt.destroyForSpecs();
});
it('draws with blend color', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
blending : {
enabled : true,
color : {
red : 0.5,
green : 0.5,
blue : 0.5,
alpha : 0.5
},
equationRgb : WebGLConstants.FUNC_SUBTRACT,
equationAlpha : WebGLConstants.FUNC_SUBTRACT,
functionSourceRgb : WebGLConstants.CONSTANT_COLOR,
functionSourceAlpha : WebGLConstants.ONE,
functionDestinationRgb : WebGLConstants.ZERO,
functionDestinationAlpha : WebGLConstants.ZERO
}
})
});
// 2 of 3: Blend: RGB: 255 - 127, Alpha: 255 - (255 - 255)
// Epsilon of 1 because ANGLE gives 127 and desktop GL gives 128.
command.execute(context);
expect({
context : context,
epsilon : 1
}).toReadPixels([128, 128, 128, 255]);
});
it('draws with culling', function() {
var vs = 'attribute vec4 position; void main() { gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([-1000, -1000, 0, 1, 1000, -1000, 0, 1, -1000, 1000, 0, 1, 1000, 1000, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
// 1 of 3: Clear to black
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 2 of 3: Cull front faces - nothing is drawn
var command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
cull : {
enabled : true,
face : WebGLConstants.FRONT
}
})
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 3 of 3: Cull back faces - nothing is culled
command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
cull : {
enabled : true,
face : WebGLConstants.BACK
}
})
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws with front face winding order', function() {
var vs = 'attribute vec4 position; void main() { gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([-1000, -1000, 0, 1, 1000, -1000, 0, 1, -1000, 1000, 0, 1, 1000, 1000, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
// 1 of 3: Clear to black
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 2 of 3: Cull back faces with opposite winding order - nothing is drawn
var command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
frontFace : WindingOrder.CLOCKWISE,
cull : {
enabled : true,
face : WebGLConstants.BACK
}
})
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 3 of 3: Cull back faces with correct winding order - nothing is culled
command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
frontFace : WindingOrder.COUNTER_CLOCKWISE,
cull : {
enabled : true,
face : WebGLConstants.BACK
}
})
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws with the depth test', function() {
var vs = 'attribute vec4 position; void main() { gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([-1000, -1000, 0, 1, 1000, -1000, 0, 1, -1000, 1000, 0, 1, 1000, 1000, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
var command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
depthTest : {
enabled : true,
func : WebGLConstants.LEQUAL
}
})
});
// 1 of 2. Triangle fan passes the depth test.
var clearCommand = new ClearCommand({
color : new Color (0.0, 0.0, 0.0, 0.0),
depth : 1.0
});
clearCommand.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
// 2 of 2. Triangle fan fails the depth test.
clearCommand.color = new Color (0.0, 0.0, 0.0, 0.0);
clearCommand.depth = 0.0;
clearCommand.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
});
it('draws with depth range', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, 0.0, 1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
depthRange : {
near : 0.25,
far : 0.75
}
})
});
command.execute(context);
expect(context).toReadPixels([64, 191, 0, 255]);
});
it('draws with line width', function() {
var vs = 'attribute vec4 position; void main() { gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([-1000, -1000, 0, 1, 1000, 1000, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.LINES,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
lineWidth : ContextLimits.maximumAliasedLineWidth
// May only be 1.
})
});
command.execute(context);
// I believe different GL implementations are allowed to AA
// in different ways (or at least that is what we see in practice),
// so verify it at least rendered something.
expect(context).notToReadPixels([0, 0, 0, 255]);
});
it('draws with polygon offset', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
polygonOffset : {
enabled : true,
factor : 1,
units : 1
}
})
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws with sample coverage', function() {
if (!context.antialias) {
// Sample coverage requires antialiasing.
return;
}
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
sampleCoverage : {
enabled : true,
value : 0,
invert : false
}
})
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
sampleCoverage : {
enabled : false
}
})
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws with stencil test (front)', function() {
if (context.stencilBits === 0) {
return;
}
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([-1000, -1000, 0, 1, 1000, -1000, 0, 1, -1000, 1000, 0, 1, 1000, 1000, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
var rs = RenderState.fromCache({
stencilTest : {
enabled : true,
frontFunction : WebGLConstants.EQUAL,
reference : 1,
mask : 1
}
});
// 1 of 4. Clear, including stencil
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 2 of 4. Render where stencil is set - nothing is drawn
var command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : rs
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 3 of 4. Render to stencil only, increment
command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
colorMask : {
red : false,
green : false,
blue : false,
alpha : false
},
stencilTest : {
enabled : true,
frontOperation : {
zPass : WebGLConstants.INCR
}
}
})
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 4 of 4. Render where stencil is set
command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : rs
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws with stencil test (back)', function() {
if (context.stencilBits === 0) {
return;
}
var vs = 'attribute vec4 position; void main() { gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([-1000, -1000, 0, 1, 1000, -1000, 0, 1, -1000, 1000, 0, 1, 1000, 1000, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
var rs = RenderState.fromCache({
frontFace : WindingOrder.CLOCKWISE,
stencilTest : {
enabled : true,
backFunction : WebGLConstants.NOTEQUAL,
reference : 0
}
});
// 1 of 4. Clear, including stencil
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 2 of 4. Render where stencil is set - nothing is drawn
var command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : rs
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 3 of 4. Render to stencil only, increment
command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : RenderState.fromCache({
frontFace : WindingOrder.CLOCKWISE,
colorMask : {
red : false,
green : false,
blue : false,
alpha : false
},
stencilTest : {
enabled : true,
backOperation : {
zPass : WebGLConstants.INVERT
}
}
})
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// 4 of 4. Render where stencil is set
command = new DrawCommand({
primitiveType : PrimitiveType.TRIANGLE_STRIP,
shaderProgram : sp,
vertexArray : va,
renderState : rs
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws with an offset and count', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, -1, 0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
// The first point in the vertex buffer does not generate any pixels
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
offset : 0,
count : 1,
shaderProgram : sp,
vertexArray : va
});
command.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
offset : 1,
count : 1,
shaderProgram : sp,
vertexArray : va
});
command.execute(context);
expect(context).toReadPixels([255, 255, 255, 255]);
});
it('draws two instances of a point with different per-instance colors', function() {
if (context.instancedArrays) {
var vs =
'attribute vec4 position;' +
'attribute vec4 color;' +
'varying vec4 v_color;' +
'void main() {' +
' gl_PointSize = 1.0; ' +
' gl_Position = position;' +
' v_color = color;' +
'}';
var fs = 'varying vec4 v_color; void main() { gl_FragColor = v_color; }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0,
color: 1
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}, {
index : 1,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Uint8Array([255, 0, 0, 255, 0, 255, 0, 255]),
usage : BufferUsage.STATIC_DRAW
}),
componentDatatype : ComponentDatatype.UNSIGNED_BYTE,
componentsPerAttribute : 4,
normalize : true,
instanceDivisor : 1
}]
});
ClearCommand.ALL.execute(context);
expect(context).toReadPixels([0, 0, 0, 255]);
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
instanceCount : 2,
renderState : RenderState.fromCache({
blending : BlendingState.ADDITIVE_BLEND
})
});
command.execute(context);
expect(context).toReadPixels([255, 255, 0, 255]);
}
});
it('fails to draw (missing command)', function() {
expect(function() {
context.draw();
}).toThrowDeveloperError();
});
it('fails to draw (missing shaderProgram)', function() {
expect(function() {
context.draw({
primitiveType : PrimitiveType.POINTS
});
}).toThrowDeveloperError();
});
it('fails to draw (missing primitiveType)', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs
});
expect(function() {
context.draw({
shaderProgram : sp
});
}).toThrowDeveloperError();
});
it('fails to draw (primitiveType)', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs
});
expect(function() {
context.draw({
primitiveType : 'invalid value',
shaderProgram : sp
});
}).toThrowDeveloperError();
});
it('fails to draw (missing vertexArray)', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs
});
expect(function() {
context.draw({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp
});
}).toThrowDeveloperError();
});
it('fails to draw (negative offset)', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs
});
expect(function() {
context.draw({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : new VertexArray({
context : context
}),
offset : -1,
count : 1
});
}).toThrowDeveloperError();
});
it('throws if instanceCount is less than one', function() {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
instanceCount : -1
});
expect(function() {
command.execute(context);
}).toThrowDeveloperError();
});
it('throws when instanceCount is greater than one and the instanced arrays extension is not supported', function() {
if (!context.instancedArrays) {
var vs = 'attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }';
var fs = 'void main() { gl_FragColor = vec4(1.0); }';
sp = ShaderProgram.fromCache({
context : context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations: {
position: 0
}
});
va = new VertexArray({
context : context,
attributes : [{
index : 0,
vertexBuffer : Buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0, 1]),
usage : BufferUsage.STATIC_DRAW
}),
componentsPerAttribute : 4
}]
});
var command = new DrawCommand({
primitiveType : PrimitiveType.POINTS,
shaderProgram : sp,
vertexArray : va,
instanceCount : 2
});
expect(function() {
command.execute(context);
}).toThrowDeveloperError();
}
});
}, 'WebGL');