Skip to content

Commit ccfb19e

Browse files
committed
Minor improvements for WebGL 2 and development.
- Basic support for texSubImage3D. - Code support for Renderdoc, which is enabled via a define. - Fix for nodejs issue with detecting instances of buffer types. - Simple conversion for RGBA->RED pixel formats on texture upload.
1 parent 4dcb180 commit ccfb19e

File tree

5 files changed

+886
-26
lines changed

5 files changed

+886
-26
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,12 @@ Once this is done, you should be good to go! A few more things
257257

258258
Note: the `gl-conformance` package is currently hosted on GitHub Package Registry. To install from there, you may need to add `//npm.pkg.github.com` to your user directory's `.npmrc` file
259259

260+
### Debugging with RenderDoc
261+
262+
To debug with RenderDoc, you can set the `RENDERDOC_ENABLED` define in the `src/native/webgl.cc` file.
263+
264+
You'll need to also install RenderDoc and attach it to the gl process when you launch your program. The easiest way to attach to the running process is to uncomment the MessageBoxA call in the `src/native/webgl.cc` file.
265+
260266
## License
261267

262268
See LICENSES

src/javascript/utils.js

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,27 @@ function checkObject (object) {
2626
(object === undefined)
2727
}
2828

29+
// Works around the fact that "instanceof" doesn't work for polyfilled types
30+
function isInstanceOfType (instance, type) {
31+
return Object.prototype.toString.call(instance) === `[object ${type}]`
32+
}
33+
2934
function checkUniform (program, location) {
3035
return location instanceof WebGLUniformLocation &&
3136
location._program === program &&
3237
location._linkCount === program._linkCount
3338
}
3439

3540
function isTypedArray (data) {
36-
return data instanceof Uint8Array ||
37-
data instanceof Uint8ClampedArray ||
38-
data instanceof Int8Array ||
39-
data instanceof Uint16Array ||
40-
data instanceof Int16Array ||
41-
data instanceof Uint32Array ||
42-
data instanceof Int32Array ||
43-
data instanceof Float32Array ||
44-
data instanceof Float64Array
41+
return isInstanceOfType(data, 'Uint8Array') ||
42+
isInstanceOfType(data, 'Uint8ClampedArray') ||
43+
isInstanceOfType(data, 'Int8Array') ||
44+
isInstanceOfType(data, 'Uint16Array') ||
45+
isInstanceOfType(data, 'Int16Array') ||
46+
isInstanceOfType(data, 'Uint32Array') ||
47+
isInstanceOfType(data, 'Int32Array') ||
48+
isInstanceOfType(data, 'Float32Array') ||
49+
isInstanceOfType(data, 'Float64Array')
4550
}
4651

4752
// Don't allow: ", $, `, @, \, ', \0
@@ -159,6 +164,23 @@ function extractImageData (pixels) {
159164
return null
160165
}
161166

167+
function convertPixelFormats (ctx, pixels, srcFormat, dstFormat) {
168+
switch (srcFormat) {
169+
case ctx.RGBA:
170+
switch (dstFormat) {
171+
case ctx.RGBA:
172+
return pixels
173+
case ctx.RED:
174+
// extract the red channel from pixels, which is in typed array format, and convert to Uint8Array
175+
return new Uint8Array(pixels.filter((_, i) => i % 4 === 0))
176+
default:
177+
throw new Error('unsupported destination format')
178+
}
179+
default:
180+
throw new Error('unsupported source format')
181+
}
182+
}
183+
162184
function formatSize (internalFormat) {
163185
switch (internalFormat) {
164186
case gl.ALPHA:
@@ -176,14 +198,14 @@ function formatSize (internalFormat) {
176198

177199
function convertPixels (pixels) {
178200
if (typeof pixels === 'object' && pixels !== null) {
179-
if (pixels instanceof ArrayBuffer) {
201+
if (isInstanceOfType(pixels, 'ArrayBuffer')) {
180202
return new Uint8Array(pixels)
181-
} else if (pixels instanceof Uint8Array ||
182-
pixels instanceof Uint16Array ||
183-
pixels instanceof Uint8ClampedArray ||
184-
pixels instanceof Float32Array) {
203+
} else if (isInstanceOfType(pixels, 'Uint8Array') ||
204+
isInstanceOfType(pixels, 'Uint16Array') ||
205+
isInstanceOfType(pixels, 'Uint8ClampedArray') ||
206+
isInstanceOfType(pixels, 'Float32Array')) {
185207
return unpackTypedArray(pixels)
186-
} else if (pixels instanceof Buffer) {
208+
} else if (isInstanceOfType(pixels, 'Buffer')) {
187209
return new Uint8Array(pixels)
188210
}
189211
}
@@ -218,6 +240,7 @@ module.exports = {
218240
uniformTypeSize,
219241
unpackTypedArray,
220242
extractImageData,
243+
convertPixelFormats,
221244
formatSize,
222245
checkFormat,
223246
checkUniform,

src/javascript/webgl-rendering-context.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const {
2020
typeSize,
2121
uniformTypeSize,
2222
extractImageData,
23+
convertPixelFormats,
2324
isTypedArray,
2425
unpackTypedArray,
2526
convertPixels,
@@ -2303,6 +2304,8 @@ class WebGLRenderingContextHelper extends NativeWebGLRenderingContext {
23032304
width = pixels.width
23042305
height = pixels.height
23052306
pixels = pixels.data
2307+
2308+
pixels = convertPixelFormats(this, pixels, this.RGBA, format)
23062309
}
23072310

23082311
target |= 0
@@ -2373,6 +2376,8 @@ class WebGLRenderingContextHelper extends NativeWebGLRenderingContext {
23732376
width = pixels.width
23742377
height = pixels.height
23752378
pixels = pixels.data
2379+
2380+
pixels = convertPixelFormats(this, pixels, this.RGBA, format)
23762381
}
23772382

23782383
if (typeof pixels !== 'object') {
@@ -2393,6 +2398,27 @@ class WebGLRenderingContextHelper extends NativeWebGLRenderingContext {
23932398
data)
23942399
}
23952400

2401+
texSubImage3D (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) {
2402+
if (pixels === null || pixels === undefined) {
2403+
return
2404+
}
2405+
2406+
if (typeof pixels !== 'object') {
2407+
throw new TypeError('texSubImage3D(GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLenum, GLenum, Uint8Array)')
2408+
}
2409+
2410+
if (
2411+
typeof pixels.width !== 'undefined' &&
2412+
typeof pixels.height !== 'undefined'
2413+
) {
2414+
pixels = extractImageData(pixels).data
2415+
pixels = convertPixelFormats(this, pixels, this.RGBA, format)
2416+
}
2417+
const data = convertPixels(pixels)
2418+
2419+
super.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data)
2420+
}
2421+
23962422
texParameterf (target, pname, param) {
23972423
target |= 0
23982424
pname |= 0

0 commit comments

Comments
 (0)