You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1034 lines
29 KiB
JavaScript
1034 lines
29 KiB
JavaScript
import { Color } from "../../Source/Cesium.js";
|
|
import { PixelFormat } from "../../Source/Cesium.js";
|
|
import { PrimitiveType } from "../../Source/Cesium.js";
|
|
import { WebGLConstants } from "../../Source/Cesium.js";
|
|
import { Buffer } from "../../Source/Cesium.js";
|
|
import { BufferUsage } from "../../Source/Cesium.js";
|
|
import { ClearCommand } from "../../Source/Cesium.js";
|
|
import { ContextLimits } from "../../Source/Cesium.js";
|
|
import { CubeMap } from "../../Source/Cesium.js";
|
|
import { DrawCommand } from "../../Source/Cesium.js";
|
|
import { Framebuffer } from "../../Source/Cesium.js";
|
|
import { PixelDatatype } from "../../Source/Cesium.js";
|
|
import { Renderbuffer } from "../../Source/Cesium.js";
|
|
import { RenderbufferFormat } from "../../Source/Cesium.js";
|
|
import { RenderState } from "../../Source/Cesium.js";
|
|
import { ShaderProgram } from "../../Source/Cesium.js";
|
|
import { Texture } from "../../Source/Cesium.js";
|
|
import { VertexArray } from "../../Source/Cesium.js";
|
|
import createContext from "../createContext.js";
|
|
|
|
describe(
|
|
"Renderer/Framebuffer",
|
|
function () {
|
|
var context;
|
|
var sp;
|
|
var va;
|
|
var framebuffer;
|
|
|
|
beforeAll(function () {
|
|
context = createContext();
|
|
});
|
|
|
|
afterAll(function () {
|
|
context.destroyForSpecs();
|
|
});
|
|
|
|
afterEach(function () {
|
|
sp = sp && sp.destroy();
|
|
va = va && va.destroy();
|
|
framebuffer = framebuffer && framebuffer.destroy();
|
|
});
|
|
|
|
it("has a color texture attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
});
|
|
expect(framebuffer.getColorTexture(0)).toBeDefined();
|
|
});
|
|
|
|
it("has a color renderbuffer attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorRenderbuffers: [
|
|
new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.RGBA4,
|
|
}),
|
|
],
|
|
});
|
|
expect(framebuffer.getColorRenderbuffer(0)).toBeDefined();
|
|
});
|
|
|
|
it("has a depth texture attachment", function () {
|
|
if (context.depthTexture) {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthTexture: new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelFormat: PixelFormat.DEPTH_COMPONENT,
|
|
pixelDatatype: PixelDatatype.UNSIGNED_SHORT,
|
|
}),
|
|
});
|
|
expect(framebuffer.depthTexture).toBeDefined();
|
|
}
|
|
});
|
|
|
|
it("has a depth renderbuffer attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthRenderbuffer: new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.DEPTH_COMPONENT16,
|
|
}),
|
|
});
|
|
expect(framebuffer.depthRenderbuffer).toBeDefined();
|
|
});
|
|
|
|
it("has a stencil renderbuffer attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
stencilRenderbuffer: new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.STENCIL_INDEX8,
|
|
}),
|
|
});
|
|
expect(framebuffer.stencilRenderbuffer).toBeDefined();
|
|
});
|
|
|
|
it("has a depth-stencil texture attachment", function () {
|
|
if (context.depthTexture) {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthStencilTexture: new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelFormat: PixelFormat.DEPTH_STENCIL,
|
|
pixelDatatype: PixelDatatype.UNSIGNED_INT_24_8,
|
|
}),
|
|
});
|
|
expect(framebuffer.depthStencilTexture).toBeDefined();
|
|
}
|
|
});
|
|
|
|
it("has a depth-stencil renderbuffer attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthStencilRenderbuffer: new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.DEPTH_STENCIL,
|
|
}),
|
|
});
|
|
expect(framebuffer.depthStencilRenderbuffer).toBeDefined();
|
|
});
|
|
|
|
it("has a depth attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
});
|
|
expect(framebuffer.hasDepthAttachment).toEqual(false);
|
|
framebuffer.destroy();
|
|
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthRenderbuffer: new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.DEPTH_COMPONENT16,
|
|
}),
|
|
});
|
|
expect(framebuffer.hasDepthAttachment).toEqual(true);
|
|
});
|
|
|
|
it("clears a color attachment", function () {
|
|
// 1 of 3. Clear default color buffer to black.
|
|
ClearCommand.ALL.execute(context);
|
|
expect(context).toReadPixels([0, 0, 0, 255]);
|
|
|
|
// 2 of 3. Clear framebuffer color attachment to green.
|
|
var colorTexture = new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
});
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [colorTexture],
|
|
});
|
|
|
|
var clearCommand = new ClearCommand({
|
|
color: new Color(0.0, 1.0, 0.0, 1.0),
|
|
framebuffer: framebuffer,
|
|
});
|
|
clearCommand.execute(context);
|
|
|
|
// 3 of 3. Render green to default color buffer by reading from previous color attachment
|
|
var fs =
|
|
"uniform sampler2D u_texture; void main() { gl_FragColor = texture2D(u_texture, vec2(0.0)); }";
|
|
var uniformMap = {
|
|
u_texture: function () {
|
|
return colorTexture;
|
|
},
|
|
};
|
|
|
|
expect({
|
|
context: context,
|
|
fragmentShader: fs,
|
|
uniformMap: uniformMap,
|
|
}).contextToRender([0, 255, 0, 255]);
|
|
});
|
|
|
|
it("clears a cube map face color attachment", function () {
|
|
var cubeMap = new CubeMap({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
});
|
|
|
|
// 1 of 3. Clear default color buffer to black.
|
|
ClearCommand.ALL.execute(context);
|
|
expect(context).toReadPixels([0, 0, 0, 255]);
|
|
|
|
// 2 of 3. Clear framebuffer color attachment to green.
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [cubeMap.positiveX],
|
|
destroyAttachments: false,
|
|
});
|
|
|
|
var clearCommand = new ClearCommand({
|
|
color: new Color(0.0, 1.0, 0.0, 1.0),
|
|
framebuffer: framebuffer,
|
|
});
|
|
clearCommand.execute(context);
|
|
|
|
// 3 of 3. Render green to default color buffer by reading from previous color attachment
|
|
var fs =
|
|
"uniform samplerCube u_cubeMap; void main() { gl_FragColor = textureCube(u_cubeMap, vec3(1.0, 0.0, 0.0)); }";
|
|
var uniformMap = {
|
|
u_cubeMap: function () {
|
|
return cubeMap;
|
|
},
|
|
};
|
|
|
|
expect({
|
|
context: context,
|
|
fragmentShader: fs,
|
|
uniformMap: uniformMap,
|
|
}).contextToRender([0, 255, 0, 255]);
|
|
|
|
cubeMap = cubeMap.destroy();
|
|
});
|
|
|
|
function renderColorTexture(framebuffer, color, expectedColor) {
|
|
var vs =
|
|
"attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }";
|
|
var fs = "uniform vec4 color; void main() { gl_FragColor = color; }";
|
|
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 uniformMap = {
|
|
color: function () {
|
|
return color;
|
|
},
|
|
};
|
|
|
|
var command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp,
|
|
vertexArray: va,
|
|
uniformMap: uniformMap,
|
|
framebuffer: framebuffer,
|
|
});
|
|
command.execute(context);
|
|
|
|
expect({
|
|
context: context,
|
|
framebuffer: framebuffer,
|
|
}).toReadPixels(expectedColor);
|
|
}
|
|
|
|
it("draws to a color attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
});
|
|
renderColorTexture(framebuffer, new Color(0.0, 1.0, 0.0, 1.0), [
|
|
0,
|
|
255,
|
|
0,
|
|
255,
|
|
]);
|
|
});
|
|
|
|
it("draws to a floating-point color attachment", function () {
|
|
if (!context.colorBufferFloat) {
|
|
return;
|
|
}
|
|
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelDatatype: PixelDatatype.FLOAT,
|
|
}),
|
|
],
|
|
});
|
|
renderColorTexture(framebuffer, new Color(0.5, 1.5, 2.0, 1.0), [
|
|
0.5,
|
|
1.5,
|
|
2.0,
|
|
1.0,
|
|
]);
|
|
});
|
|
|
|
it("draws to a half floating-point color attachment", function () {
|
|
if (!context.colorBufferHalfFloat) {
|
|
return;
|
|
}
|
|
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelDatatype: PixelDatatype.HALF_FLOAT,
|
|
}),
|
|
],
|
|
});
|
|
renderColorTexture(framebuffer, new Color(0.5, 1.5, 2.0, 1.0), [
|
|
14336,
|
|
15872,
|
|
16384,
|
|
15360,
|
|
]);
|
|
});
|
|
|
|
function renderDepthAttachment(framebuffer, texture) {
|
|
ClearCommand.ALL.execute(context);
|
|
|
|
var framebufferClear = new ClearCommand({
|
|
depth: 1.0,
|
|
framebuffer: framebuffer,
|
|
});
|
|
|
|
framebufferClear.execute(context);
|
|
|
|
// 1 of 3. Render green point into color attachment.
|
|
var vs =
|
|
"attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }";
|
|
var fs = "void main() { gl_FragColor = vec4(0.0, 1.0, 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,
|
|
},
|
|
],
|
|
});
|
|
|
|
var command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp,
|
|
vertexArray: va,
|
|
framebuffer: framebuffer,
|
|
renderState: RenderState.fromCache({
|
|
depthTest: {
|
|
enabled: true,
|
|
},
|
|
}),
|
|
});
|
|
command.execute(context);
|
|
|
|
// 2 of 3. Verify default color buffer is still black.
|
|
expect(context).toReadPixels([0, 0, 0, 255]);
|
|
|
|
// 3 of 3. Render green to default color buffer by reading from previous color attachment
|
|
var vs2 =
|
|
"attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }";
|
|
var fs2 =
|
|
"uniform sampler2D u_texture; void main() { gl_FragColor = texture2D(u_texture, vec2(0.0)).rrrr; }";
|
|
var sp2 = ShaderProgram.fromCache({
|
|
context: context,
|
|
vertexShaderSource: vs2,
|
|
fragmentShaderSource: fs2,
|
|
attributeLocations: {
|
|
position: 0,
|
|
},
|
|
});
|
|
var uniformMap = {
|
|
u_texture: function () {
|
|
return texture;
|
|
},
|
|
};
|
|
|
|
command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp2,
|
|
vertexArray: va,
|
|
uniformMap: uniformMap,
|
|
});
|
|
command.execute(context);
|
|
|
|
sp2 = sp2.destroy();
|
|
|
|
return context.readPixels();
|
|
}
|
|
|
|
it("draws to a depth texture attachment", function () {
|
|
if (context.depthTexture) {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
depthTexture: new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelFormat: PixelFormat.DEPTH_COMPONENT,
|
|
pixelDatatype: PixelDatatype.UNSIGNED_SHORT,
|
|
}),
|
|
});
|
|
|
|
if (framebuffer.status === WebGLConstants.FRAMEBUFFER_COMPLETE) {
|
|
expect(
|
|
renderDepthAttachment(framebuffer, framebuffer.depthTexture)
|
|
).toEqualEpsilon([128, 128, 128, 255], 1);
|
|
}
|
|
}
|
|
});
|
|
|
|
it("draws to a depth-stencil texture attachment", function () {
|
|
if (context.depthTexture) {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
depthStencilTexture: new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelFormat: PixelFormat.DEPTH_STENCIL,
|
|
pixelDatatype: PixelDatatype.UNSIGNED_INT_24_8,
|
|
}),
|
|
});
|
|
|
|
if (framebuffer.status === WebGLConstants.FRAMEBUFFER_COMPLETE) {
|
|
expect(
|
|
renderDepthAttachment(framebuffer, framebuffer.depthStencilTexture)
|
|
).toEqualEpsilon([128, 128, 128, 255], 1);
|
|
}
|
|
}
|
|
});
|
|
|
|
it("draws with a depth attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
depthRenderbuffer: new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.DEPTH_COMPONENT16,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
});
|
|
|
|
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,
|
|
},
|
|
],
|
|
});
|
|
|
|
// 1 of 3. Clear framebuffer
|
|
var clearCommand = new ClearCommand({
|
|
color: new Color(0.0, 0.0, 0.0, 0.0),
|
|
depth: 1.0,
|
|
framebuffer: framebuffer,
|
|
});
|
|
clearCommand.execute(context);
|
|
expect({
|
|
context: context,
|
|
framebuffer: framebuffer,
|
|
}).toReadPixels([0, 0, 0, 0]);
|
|
|
|
// 2 of 3. Does not pass depth test
|
|
var command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp,
|
|
vertexArray: va,
|
|
framebuffer: framebuffer,
|
|
renderState: RenderState.fromCache({
|
|
depthTest: {
|
|
enabled: true,
|
|
func: WebGLConstants.NEVER,
|
|
},
|
|
}),
|
|
});
|
|
command.execute(context);
|
|
expect({
|
|
context: context,
|
|
framebuffer: framebuffer,
|
|
}).toReadPixels([0, 0, 0, 0]);
|
|
|
|
// 3 of 3. Passes depth test
|
|
command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp,
|
|
vertexArray: va,
|
|
framebuffer: framebuffer,
|
|
renderState: RenderState.fromCache({
|
|
depthTest: {
|
|
enabled: true,
|
|
func: WebGLConstants.ALWAYS,
|
|
},
|
|
}),
|
|
});
|
|
command.execute(context);
|
|
expect({
|
|
context: context,
|
|
framebuffer: framebuffer,
|
|
}).toReadPixels([255, 255, 255, 255]);
|
|
});
|
|
|
|
it("draws with multiple render targets", function () {
|
|
if (!context.drawBuffers) {
|
|
return;
|
|
}
|
|
|
|
var source = new Uint8Array(4);
|
|
var colorTexture0 = new Texture({
|
|
context: context,
|
|
source: {
|
|
arrayBufferView: source,
|
|
width: 1,
|
|
height: 1,
|
|
},
|
|
});
|
|
var colorTexture1 = new Texture({
|
|
context: context,
|
|
source: {
|
|
arrayBufferView: source,
|
|
width: 1,
|
|
height: 1,
|
|
},
|
|
});
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [colorTexture0, colorTexture1],
|
|
});
|
|
|
|
// 1 of 5. Clear default color buffer to black.
|
|
ClearCommand.ALL.execute(context);
|
|
expect(context).toReadPixels([0, 0, 0, 255]);
|
|
|
|
// 2 of 5. Render red point into color attachment 0 and green point to color attachment 1.
|
|
var vs =
|
|
"attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }";
|
|
var fs =
|
|
"#extension GL_EXT_draw_buffers : enable \n void main() { gl_FragData[0] = vec4(1.0, 0.0, 0.0, 1.0); gl_FragData[1] = vec4(0.0, 1.0, 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,
|
|
},
|
|
],
|
|
});
|
|
|
|
var command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp,
|
|
vertexArray: va,
|
|
framebuffer: framebuffer,
|
|
});
|
|
command.execute(context);
|
|
|
|
// 3 of 5. Verify default color buffer is still black.
|
|
expect(context).toReadPixels([0, 0, 0, 255]);
|
|
|
|
// 4 of 5. Render yellow to default color buffer by reading from previous color attachments
|
|
var vs2 =
|
|
"attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }";
|
|
var fs2 =
|
|
"uniform sampler2D u_texture0; uniform sampler2D u_texture1; void main() { gl_FragColor = texture2D(u_texture0, vec2(0.0)) + texture2D(u_texture1, vec2(0.0)); }";
|
|
var sp2 = ShaderProgram.fromCache({
|
|
context: context,
|
|
vertexShaderSource: vs2,
|
|
fragmentShaderSource: fs2,
|
|
attributeLocations: {
|
|
position: 0,
|
|
},
|
|
});
|
|
var uniformMap = {
|
|
u_texture0: function () {
|
|
return colorTexture0;
|
|
},
|
|
u_texture1: function () {
|
|
return colorTexture1;
|
|
},
|
|
};
|
|
|
|
command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp2,
|
|
vertexArray: va,
|
|
uniformMap: uniformMap,
|
|
});
|
|
command.execute(context);
|
|
expect(context).toReadPixels([255, 255, 0, 255]);
|
|
|
|
// 5 of 5. Verify clearing multiple color attachments
|
|
var clearCommand = new ClearCommand({
|
|
color: new Color(0.0, 0.0, 0.0, 0.0),
|
|
framebuffer: framebuffer,
|
|
});
|
|
clearCommand.execute(context);
|
|
|
|
command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp2,
|
|
vertexArray: va,
|
|
});
|
|
command.execute(context);
|
|
expect(context).toReadPixels([0, 0, 0, 255]);
|
|
|
|
sp2 = sp2.destroy();
|
|
});
|
|
|
|
it("gets the status of a complete framebuffer", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
depthRenderbuffer: new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.DEPTH_COMPONENT16,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
});
|
|
expect(framebuffer.status).toEqual(WebGLConstants.FRAMEBUFFER_COMPLETE);
|
|
});
|
|
|
|
it("gets the status of a incomplete framebuffer", function () {
|
|
if (!!window.webglStub) {
|
|
return;
|
|
}
|
|
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
depthRenderbuffer: new Renderbuffer({
|
|
context: context,
|
|
format: RenderbufferFormat.RGBA4,
|
|
width: 2,
|
|
height: 2,
|
|
}),
|
|
});
|
|
expect(framebuffer.status).not.toEqual(
|
|
WebGLConstants.FRAMEBUFFER_COMPLETE
|
|
);
|
|
});
|
|
|
|
it("destroys", function () {
|
|
var f = new Framebuffer({
|
|
context: context,
|
|
});
|
|
expect(f.isDestroyed()).toEqual(false);
|
|
f.destroy();
|
|
expect(f.isDestroyed()).toEqual(true);
|
|
});
|
|
|
|
it("throws when created with color texture and color renderbuffer attachments", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: "not undefined",
|
|
colorRenderbuffers: "not undefined",
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when created with depth texture and depth renderbuffer attachments", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthTexture: "not undefined",
|
|
depthRenderbuffer: "not undefined",
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when created with depth-stencil texture and depth-stencil renderbuffer attachments", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthStencilTexture: "not undefined",
|
|
depthStencilRenderbuffer: "not undefined",
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when created with depth and depth-stencil attachments", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthRenderbuffer: "not undefined",
|
|
depthStencilRenderbuffer: "not undefined",
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when created with stencil and depth-stencil attachments", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
stencilRenderbuffer: "not undefined",
|
|
depthStencilRenderbuffer: "not undefined",
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when created with depth and stencil attachments", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthRenderbuffer: "not undefined",
|
|
stencilRenderbuffer: "not undefined",
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when created with a color texture with a non-color pixel format", function () {
|
|
if (context.depthTexture) {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelFormat: PixelFormat.DEPTH_COMPONENT,
|
|
pixelDatatype: PixelDatatype.UNSIGNED_SHORT,
|
|
}),
|
|
],
|
|
});
|
|
}).toThrowDeveloperError();
|
|
}
|
|
});
|
|
|
|
it("throws when created with a depth texture without a DEPTH_COMPONENT pixel format", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthTexture: new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when created with a depth-stencil texture without a DEPTH_STENCIL pixel format", function () {
|
|
expect(function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
depthStencilTexture: new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when the depth test is enabled without an appropriate attachment", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
}),
|
|
],
|
|
});
|
|
|
|
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,
|
|
},
|
|
],
|
|
});
|
|
|
|
expect(function () {
|
|
var command = new DrawCommand({
|
|
primitiveType: PrimitiveType.POINTS,
|
|
shaderProgram: sp,
|
|
vertexArray: va,
|
|
framebuffer: framebuffer,
|
|
renderState: RenderState.fromCache({
|
|
depthTest: {
|
|
enabled: true,
|
|
},
|
|
}),
|
|
});
|
|
command.execute(context);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when the number of color texture exceeds the number color attachments supported", function () {
|
|
expect(function () {
|
|
return new Framebuffer({
|
|
context: context,
|
|
colorTextures: new Array(ContextLimits.maximumColorAttachments + 1),
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when the number of color renderbuffers exceeds the number color attachments supported", function () {
|
|
expect(function () {
|
|
return new Framebuffer({
|
|
context: context,
|
|
colorRenderbuffers: new Array(
|
|
ContextLimits.maximumColorAttachments + 1
|
|
),
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when the index to getColorTexture is out of bounds", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
});
|
|
expect(function () {
|
|
framebuffer.getColorTexture();
|
|
}).toThrowDeveloperError();
|
|
|
|
expect(function () {
|
|
framebuffer.getColorTexture(-1);
|
|
}).toThrowDeveloperError();
|
|
|
|
expect(function () {
|
|
framebuffer.getColorTexture(ContextLimits.maximumColorAttachments + 1);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when the index to getColorRenderbuffer is out of bounds", function () {
|
|
framebuffer = new Framebuffer({
|
|
context: context,
|
|
});
|
|
expect(function () {
|
|
framebuffer.getColorRenderbuffer();
|
|
}).toThrowDeveloperError();
|
|
|
|
expect(function () {
|
|
framebuffer.getColorRenderbuffer(-1);
|
|
}).toThrowDeveloperError();
|
|
|
|
expect(function () {
|
|
framebuffer.getColorRenderbuffer(
|
|
ContextLimits.maximumColorAttachments + 1
|
|
);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when a color attachment has a floating-point datatype but the EXT_color_buffer_float extension is not supported", function () {
|
|
if (context.colorBufferFloat) {
|
|
return;
|
|
}
|
|
expect(function () {
|
|
return new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelDatatype: PixelDatatype.FLOAT,
|
|
}),
|
|
],
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when a color attachment has a half floating-point datatype but the EXT_color_buffer_half_float extension is not supported", function () {
|
|
if (context.colorBufferHalfFloat) {
|
|
return;
|
|
}
|
|
expect(function () {
|
|
return new Framebuffer({
|
|
context: context,
|
|
colorTextures: [
|
|
new Texture({
|
|
context: context,
|
|
width: 1,
|
|
height: 1,
|
|
pixelDatatype: PixelDatatype.HALF_FLOAT,
|
|
}),
|
|
],
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("fails to destroy", function () {
|
|
var f = new Framebuffer({
|
|
context: context,
|
|
});
|
|
f.destroy();
|
|
|
|
expect(function () {
|
|
f.destroy();
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws when there is no context", function () {
|
|
expect(function () {
|
|
return new Framebuffer();
|
|
}).toThrowDeveloperError();
|
|
});
|
|
},
|
|
"WebGL"
|
|
);
|