luma.gl/modules/webgl/test/classes/framebuffer.spec.js
2019-03-21 15:33:26 -07:00

262 lines
7.3 KiB
JavaScript

/* eslint-disable max-len */
import test from 'tape-catch';
import GL from '@luma.gl/constants';
import {Framebuffer, Renderbuffer, Texture2D} from '@luma.gl/webgl';
import {fixture} from 'test/setup';
const TEST_CASES = [
{
title: 'Default attachments',
getOpts: gl => ({}),
pass: true
},
{
title: 'No attachments',
getOpts: gl => ({attachments: {}}),
pass: false
},
{
title: 'Simple Depth Renderbuffer + Color Texture',
getOpts: gl => ({
attachments: {
[GL.COLOR_ATTACHMENT0]: new Texture2D(gl),
[GL.DEPTH_ATTACHMENT]: new Renderbuffer(gl, {format: GL.DEPTH_COMPONENT16})
}
}),
pass: true
},
{
title: 'Simple Stencil Renderbuffer + Color Texture',
getOpts: gl => ({
attachments: {
[GL.COLOR_ATTACHMENT0]: new Texture2D(gl),
[GL.STENCIL_ATTACHMENT]: new Renderbuffer(gl, {format: GL.STENCIL_INDEX8})
}
}),
pass: true
},
{
title: 'Combined Depth/Stencil Renderbuffer + Color Texture',
getOpts: gl => ({
attachments: {
[GL.COLOR_ATTACHMENT0]: new Texture2D(gl),
[GL.DEPTH_STENCIL_ATTACHMENT]: new Renderbuffer(gl, {format: GL.DEPTH_STENCIL})
}
}),
pass: true
}
// {
// title: 'Separate Depth/Stencil Renderbuffers',
// getOpts: (gl) => ({
// attachments: {
// [GL.COLOR_ATTACHMENT0]: new Texture2D(gl),
// [GL.DEPTH]: new Renderbuffer(gl, {format: GL.DEPTH_COMPONENT16}),
// [GL.STENCIL]: new Renderbuffer(gl, {format: GL.STENCIL_INDEX8})
// }
// }),
// pass: false
// }
// {
// features: FEATURES.MULTIPLE_RENDER_TARGETS,
// getOpts(gl) {
// attachments: {
// [GL.COLOR_ATTACHMENT0]: new Texture2D(gl),
// [GL.COLOR_ARTTACHMENT1]: new Texture2D(gl),
// [GL.DEPTH]: new Renderbuffer(gl)
// }
// },
// pass: true
// }
];
test('WebGL#Framebuffer construct/delete', t => {
const {gl} = fixture;
t.throws(
() => new Framebuffer(),
/.*WebGLRenderingContext.*/,
'Framebuffer throws on missing gl context'
);
const framebuffer = new Framebuffer(gl);
t.ok(framebuffer instanceof Framebuffer, 'Framebuffer construction successful');
framebuffer.delete();
t.ok(framebuffer instanceof Framebuffer, 'Framebuffer delete successful');
framebuffer.delete();
t.ok(framebuffer instanceof Framebuffer, 'Framebuffer repeated delete successful');
t.end();
});
test('Framebuffer#getDefaultFramebuffer', t => {
const {gl} = fixture;
const framebuffer = Framebuffer.getDefaultFramebuffer(gl);
t.ok(framebuffer instanceof Framebuffer, 'getDefaultFramebuffer successful');
t.throws(
() => framebuffer.resize({width: 1000, height: 1000}),
'defaultFramebuffer.resize({width, height}) throws'
);
t.doesNotThrow(() => framebuffer.resize(), 'defaultFramebuffer.resize() successful');
t.doesNotThrow(() => framebuffer.checkStatus(), 'defaultFramebuffer status ok');
t.end();
});
function testFramebuffer(t, gl) {
for (const tc of TEST_CASES) {
let opts;
t.doesNotThrow(() => {
opts = tc.getOpts(gl);
}, `Framebuffer options constructed for "${tc.title}"`);
const testFramebufferOpts = () => {
const framebuffer = new Framebuffer(gl, opts);
framebuffer.resize({width: 1000, height: 1000});
framebuffer.checkStatus();
framebuffer.resize({width: 100, height: 100});
framebuffer.checkStatus();
framebuffer.delete({recursive: true});
};
if (tc.pass) {
t.doesNotThrow(
testFramebufferOpts,
`Framebuffer checkStatus success as expected for "${tc.title}"`
);
} else {
t.throws(
testFramebufferOpts,
`Framebuffer checkStatus failure as expected for "${tc.title}"`
);
}
}
}
test('WebGL1#Framebuffer attachments', t => {
const {gl} = fixture;
testFramebuffer(t, gl);
t.end();
});
test('WebGL2#Framebuffer attachments', t => {
const {gl2} = fixture;
if (gl2) {
testFramebuffer(t, gl2);
} else {
t.comment('WebGL2 not available, skipping tests');
}
t.end();
});
function testFramebufferResize(t, gl) {
const frameBufferOptions = {
attachments: {
[GL.COLOR_ATTACHMENT0]: new Texture2D(gl),
[GL.DEPTH_STENCIL_ATTACHMENT]: new Renderbuffer(gl, {format: GL.DEPTH_STENCIL})
}
};
const framebuffer = new Framebuffer(gl, frameBufferOptions);
framebuffer.resize({width: 1000, height: 1000});
t.equals(framebuffer.width, 1000, 'Framebuffer width updated correctly on resize');
t.equals(framebuffer.height, 1000, 'Framebuffer height updated correctly on resize');
framebuffer.checkStatus();
framebuffer.resize({width: 100, height: 100});
t.equals(framebuffer.width, 100, 'Framebuffer width updated correctly on resize');
t.equals(framebuffer.height, 100, 'Framebuffer height updated correctly on resize');
framebuffer.checkStatus();
}
test('WebGL1#Framebuffer resize', t => {
const {gl} = fixture;
testFramebufferResize(t, gl);
t.end();
});
/*
import {TEXTURE_FORMATS} from '@luma.gl/webgl/texture-formats';
const RGB_TO = {
[GL.UNSIGNED_BYTE]: (r, g, b) => [r * 256, g * 256, b * 256],
[GL.UNSIGNED_SHORT_5_6_5]: (r, g, b) => r * 32 << 11 + g * 64 << 6 + b * 32
};
// const RGB_FROM = {
// [GL.UNSIGNED_BYTE]: v => [v[0] / 256, v[1] / 256, v[2] / 256],
// [GL.UNSIGNED_SHORT_5_6_5]: v => [v >> 11 / 32, v >> 6 % 64 / 64, v % 32 * 32]
// };
const DATA = [1, 0.5, 0.25, 0.125];
const TEXTURE_DATA = {
[GL.UNSIGNED_BYTE]: new Uint8Array(RGB_TO[GL.UNSIGNED_BYTE](DATA)),
[GL.UNSIGNED_SHORT_5_6_5]: new Uint16Array(RGB_TO[GL.UNSIGNED_SHORT_5_6_5](DATA))
};
const DEFAULT_TEXTURE_DATA = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
test('WebGL2#Framebuffer texture attach and read', t => {
const {gl2} = fixture;
if (!gl2) {
t.comment('WebGL2 not available, skipping tests');
t.end();
return;
}
const framebuffer = new Framebuffer(gl2, {depth: true, width: 1, height: 1, check: false});
for (let format in TEXTURE_FORMATS) {
const textureFormat = TEXTURE_FORMATS[format];
const {dataFormat, types, compressed} = textureFormat;
format = Number(format);
if (Texture2D.isSupported(gl2, {format}) && !compressed) {
let texture;
for (const type of types) {
// texture = new Texture2D(gl2, Object.assign({format, dataFormat, type}));
// t.equals(texture.format, format,
// `Texture2D({format: ${getKey(format)}, type: ${getKey(type)}, dataFormat: ${getKey(dataFormat)}) created`);
// texture.delete()
const data = TEXTURE_DATA[type] || DEFAULT_TEXTURE_DATA;
texture = new Texture2D(gl2, {format, dataFormat, type, data, width: 1, height: 1});
t.equals(texture.format, format,
`Texture2D({format: ${getKey(format)}, type: ${getKey(type)}, dataFormat: ${getKey(dataFormat)}) created`);
framebuffer.attach({
[GL.COLOR_ATTACHMENT0]: texture
});
t.doesNotThrow(
() => framebuffer.checkStatus(),
'Framebuffer is attachment complete'
);
let pixels;
t.doesNotThrow(
() => {
pixels = radPixelsToArray(framebuffer);
},
'Framebuffer.readPixels returned'
);
t.ok(pixels, 'Received pixels');
texture.delete();
}
}
}
t.end();
});
*/