diff --git a/mediapipe/web/graph_runner/graph_runner.ts b/mediapipe/web/graph_runner/graph_runner.ts index 5d0c87b11..17ad311f1 100644 --- a/mediapipe/web/graph_runner/graph_runner.ts +++ b/mediapipe/web/graph_runner/graph_runner.ts @@ -66,6 +66,7 @@ export declare interface WasmModule { (parent: string, name: string, canRead: boolean, canWrite: boolean) => void; FS_unlink(path: string): void; + gpuOriginForWebTexturesIsBottomLeft?: boolean; errorListener?: ErrorListener; _bindTextureToCanvas: () => boolean; @@ -349,6 +350,31 @@ export class GraphRunner { this.wasmModule._setAutoRenderToScreen(enabled); } + /** + * Overrides the vertical orientation for input GpuBuffers and the automatic + * render-to-screen code. The default for our OpenGL code on other platforms + * (Android, Linux) is to use a bottom-left origin. But the default for WebGL + * is to use a top-left origin. We use WebGL default normally, and many + * calculators and graphs have platform-specific code to handle the resulting + * orientation flip. However, in order to be able to use a single graph on all + * platforms without alterations, it may be useful to send images into a web + * graph using the OpenGL orientation. Users can call this function with + * `bottomLeftIsOrigin = true` in order to enforce an orientation for all + * GpuBuffer inputs which is consistent with OpenGL on other platforms. + * This call will also vertically flip the automatic render-to-screen code as + * well, so that webcam input (for example) will render properly when passed + * through the graph still. + * NOTE: This will immediately affect GpuBuffer inputs, but must be called + * *before* graph start in order to affect the automatic render-to-screen + * code! + * @param bottomLeftIsOrigin True will flip our input GpuBuffers and auto + * render-to-screen to match the classic OpenGL orientation, while false will + * disable this feature to match the default WebGL orientation. + */ + setGpuBufferVerticalFlip(bottomLeftIsOrigin: boolean): void { + this.wasmModule.gpuOriginForWebTexturesIsBottomLeft = bottomLeftIsOrigin; + } + /** * Bind texture to our internal canvas, and upload image source to GPU. * Returns tuple [width, height] of texture. Intended for internal usage. @@ -374,8 +400,14 @@ export class GraphRunner { 'Failed to obtain WebGL context from the provided canvas. ' + '`getContext()` should only be invoked with `webgl` or `webgl2`.'); } + if (this.wasmModule.gpuOriginForWebTexturesIsBottomLeft) { + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + } gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageSource); + if (this.wasmModule.gpuOriginForWebTexturesIsBottomLeft) { + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + } let width, height; if ((imageSource as HTMLVideoElement).videoWidth) {