Skip to content

Commit

Permalink
Merge pull request #313 from akashic-games/support-webgl-depth
Browse files Browse the repository at this point in the history
feat: support `RendererCandidate`
  • Loading branch information
yu-ogi authored May 15, 2024
2 parents 19fc379 + 0724f47 commit 807597c
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 20 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## 2.10.0
* @akashic/pdi-types@1.14.0 に更新
* `RendererCandidate` をサポート
* `WebGLRenderer` で部分的に depth buffer をサポートするように

## 2.9.2
* `HTMLAudioPlayer#play()` で同じ audio が連続で再生された時にエラーとなる不具合を修正

Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@akashic/pdi-browser",
"version": "2.9.2",
"version": "2.10.0",
"description": "An akashic-pdi implementation for Web browsers",
"main": "index.js",
"typings": "lib/full/index.d.ts",
Expand Down Expand Up @@ -43,7 +43,7 @@
"devDependencies": {
"@akashic/amflow": "^3.3.0",
"@akashic/eslint-config": "^2.0.0",
"@akashic/pdi-types": "^1.13.0",
"@akashic/pdi-types": "^1.14.0",
"@akashic/playlog": "^3.3.0",
"@types/jest": "^29.2.0",
"@types/node": "^18.0.0",
Expand Down
3 changes: 2 additions & 1 deletion src/ResourceFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type * as pdi from "@akashic/pdi-types";
import type { RendererCandidate } from "@akashic/pdi-types";
import type { AudioAsset } from "./asset/AudioAsset";
import { BinaryAsset } from "./asset/BinaryAsset";
import { GeneratedSVGImageAsset } from "./asset/GeneratedSVGImageAsset";
Expand All @@ -23,7 +24,7 @@ export interface ResourceFactoryParameterObject {
export class ResourceFactory implements pdi.ResourceFactory {
_audioPluginManager: AudioPluginManager;
_audioManager: AudioManager;
_rendererCandidates: string[] | undefined;
_rendererCandidates: (string | RendererCandidate)[] | undefined;
_surfaceFactory: SurfaceFactory;
_platform: Platform;

Expand Down
40 changes: 35 additions & 5 deletions src/canvas/RenderingHelper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import type { RendererCandidate } from "@akashic/pdi-types";

interface WebGLRendererCandidate extends RendererCandidate {
type: "webgl";
options?: {
enableDepthBuffer: boolean;
};
}

export module RenderingHelper {
export function toPowerOfTwo(x: number): number {
if ((x & (x - 1)) !== 0) {
Expand All @@ -14,11 +23,32 @@ export module RenderingHelper {
return Math.min(Math.max(x, 0.0), 1.0);
}

export function usedWebGL(rendererCandidates?: string[]): boolean {
let used = false;
if (rendererCandidates && (0 < rendererCandidates.length)) {
used = (rendererCandidates[0] === "webgl");
export function usedWebGL(rendererCandidates?: (string | RendererCandidate)[]): false | Required<WebGLRendererCandidate> {
if (!rendererCandidates || rendererCandidates.length === 0) {
return false;
}

const candidate = rendererCandidates[0];

if (typeof candidate === "string") {
if (candidate === "webgl") {
return {
type: "webgl",
options: {
enableDepthBuffer: false
}
};
}
} else if (candidate.type === "webgl") {
const webglRendererCandidate = candidate as WebGLRendererCandidate;
return {
type: "webgl",
options: {
enableDepthBuffer: !!webglRendererCandidate.options?.enableDepthBuffer
}
};
}
return used;

return false;
}
}
10 changes: 6 additions & 4 deletions src/canvas/shims/SurfaceFactory.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { RendererCandidate } from "@akashic/pdi-types";
import type { CanvasSurface } from "../CanvasSurface";
import { Context2DSurface } from "../context2d/Context2DSurface";
import { RenderingHelper } from "../RenderingHelper";
Expand All @@ -8,18 +9,19 @@ export class SurfaceFactory {
_shared: WebGLSharedObject | undefined;
_disposer: CanvasDisposer = new CanvasDisposer();

createPrimarySurface(width: number, height: number, rendererCandidates?: string[]): CanvasSurface {
if (RenderingHelper.usedWebGL(rendererCandidates)) {
createPrimarySurface(width: number, height: number, rendererCandidates?: (string | RendererCandidate)[]): CanvasSurface {
const usedWebGL = RenderingHelper.usedWebGL(rendererCandidates);
if (usedWebGL) {
if (!this._shared) {
this._shared = new WebGLSharedObject(width, height);
this._shared = new WebGLSharedObject({ width, height, enableDepthBuffer: usedWebGL.options.enableDepthBuffer });
}
return this._shared.getPrimarySurface();
} else {
return new Context2DSurface(width, height);
}
}

createBackSurface(width: number, height: number, rendererCandidates?: string[]): CanvasSurface {
createBackSurface(width: number, height: number, rendererCandidates?: (string | RendererCandidate)[]): CanvasSurface {
const surface = RenderingHelper.usedWebGL(rendererCandidates)
? this._shared!.createBackSurface(width, height)
: new Context2DSurface(width, height);
Expand Down
28 changes: 26 additions & 2 deletions src/canvas/webgl/WebGLSharedObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,22 @@ export interface RenderTarget {
texture: WebGLTexture | null;
}

export interface WebGLSharedObjectParameterObject {
width: number;
height: number;

/**
* depth buffer を有効にするかどうか。
* 本値が指定された場合、`this.clear()` 時に depth buffer がクリアされることに注意。
* 本値は実験的なオプションのため、将来的に挙動が変更される可能性がある。
*/
enableDepthBuffer?: boolean;
}

export class WebGLSharedObject {
private _context: WebGLRenderingContext;
private _surface: WebGLPrimarySurface;
private _enableDepthBuffer: boolean;

private _renderTarget: RenderTarget = undefined!;
private _defaultShaderProgram: WebGLShaderProgram = undefined!;
Expand All @@ -48,13 +61,17 @@ export class WebGLSharedObject {
private _compositeOps: {[key in pdi.CompositeOperationString]: [number, number]; } = undefined!;
private _deleteRequestedTargets: RenderTarget[] = undefined!;

constructor(width: number, height: number) {
constructor(params: WebGLSharedObjectParameterObject) {
const width = params.width;
const height = params.height;
const enableDepthBuffer = !!params.enableDepthBuffer;
const surface = new WebGLPrimarySurface(this, width, height);
const context = surface.canvas.getContext("webgl", { depth: false, preserveDrawingBuffer: true });
const context = surface.canvas.getContext("webgl", { depth: enableDepthBuffer, preserveDrawingBuffer: true });
if (!context) {
throw new Error("WebGLSharedObject#constructor: could not initialize WebGLRenderingContext");
}

this._enableDepthBuffer = enableDepthBuffer;
this._surface = surface;
this._context = context;
this._init();
Expand Down Expand Up @@ -105,6 +122,13 @@ export class WebGLSharedObject {
}

clear(): void {
if (this._enableDepthBuffer) {
this._context.depthMask(true); // NOTE: 既存の描画に影響を与えないよう、クリア時のみ有効にする
this._context.clear(this._context.COLOR_BUFFER_BIT | this._context.DEPTH_BUFFER_BIT);
this._context.depthMask(false);
return;
}

this._context.clear(this._context.COLOR_BUFFER_BIT);
}

Expand Down

0 comments on commit 807597c

Please sign in to comment.