Compare commits

..
6 Commits
Author SHA1 Message Date
MrKBear 80173d580e Implement ResourceHandler. 2023-02-09 16:06:47 +08:00
MrKBear 067baf8c72 Remove ResourceType. 2023-02-09 14:28:33 +08:00
MrKBear d991d96ecb Remove ResourceType. 2023-02-09 14:27:47 +08:00
MrKBear 83dac5289f Unified virtual renderer resource naming. 2023-02-09 11:02:35 +08:00
MrKBear c494156983 Detach the GL context state to a separate module. 2023-02-09 09:50:44 +08:00
MrKBear 4cd5ebb936 Rename WebGLCanvas.canvas to WebGLCanvas.element. 2023-02-03 08:51:58 +08:00
16 changed files with 232 additions and 32 deletions
+5 -3
View File
@@ -4,23 +4,25 @@
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { WebGLCanvas, EventEmitter } from "@ray-lab/renderer-webgl";
import { WebGLRenderer } from "@ray-lab/renderer-webgl";
const contentRef = ref<HTMLDivElement>();
const canvasEle = document.createElement("canvas");
onMounted(() => {
const c = new WebGLCanvas({
const renderer = new WebGLRenderer({
canvas: canvasEle,
container: contentRef.value,
autoResize: true,
width: 800,
height: 600
});
// c.on("resize", () => { console.log(c.canvas.width, c.canvas.height) });
if (contentRef.value) {
contentRef.value.appendChild(canvasEle);
}
console.log(renderer);
})
</script>
@@ -1,10 +1,18 @@
import type { ResourceSet } from "./ResourceType";
type ResourceNameType = string | number;
type ResourceIdType = string | number | symbol;
interface Resource {
type: ResourceSet;
/**
* Unique identification of resource type.
*/
type: ResourceNameType;
id: string | number;
/**
* Unique number of the resource instance.
*/
id: ResourceIdType;
}
export type { Resource };
export type { Resource, ResourceNameType, ResourceIdType };
@@ -0,0 +1,10 @@
import type { ShaderResource } from "./ShaderResource";
namespace ResourceName {
export type Shader = ShaderResource["type"];
}
type ResourceSet = ShaderResource;
type ResourceNameSet = ResourceName.Shader;
export type { ResourceName, ResourceNameSet, ResourceSet };
@@ -1,9 +0,0 @@
namespace ResourceType {
export type Shader = "SHADER" | 100_001;
}
type ResourceSet = ResourceType.Shader;
export type { ResourceType, ResourceSet };
@@ -0,0 +1,8 @@
import type { Resource } from "./Resource";
interface ShaderResource extends Resource {
type: "SHADER" | 100_001;
}
export type { ShaderResource };
@@ -4,4 +4,5 @@ export * from "command/CommandType";
export * from "command/RenderCommand";
export * from "command/ClearCommand";
export * from "resource/Resource";
export * from "resource/ResourceType";
export * from "resource/ResourceSet";
export * from "resource/ShaderResource";
@@ -0,0 +1,63 @@
import { Resource, ResourceNameType, ResourceIdType } from "@ray-lab/renderer-virtual";
/**
* Resource processing tools.
* Whenever a new resource setting is received,
* an instance of this class will be instantiated to manage the received resource.
* @typeParam ResourceOption - Resource option type.
*/
abstract class ResourceHandler<ResourceOption extends Resource = Resource> {
/**
* Resource type enumeration.
*/
public static resourceType: ResourceNameType;
public static resourceTypeAlias: ResourceNameType;
/**
* Original resource option.
*/
public resourceOption: ResourceOption;
/**
* Resource unique number.
*/
public resourceId: ResourceIdType;
/**
* @param resourceOption - Resource option.
*/
public constructor(resourceOption: ResourceOption) {
this.resourceOption = resourceOption;
this.resourceId = resourceOption.id ?? Symbol(resourceOption.type);
}
/**
* Resource initialization lifecycle.
* It will be called once after `WebGLState` is ready.
*/
public abstract setup(): any;
/**
* Marks whether the instance is destroyed.
*/
public isDestroyed: boolean = false;
/**
* Resource destruction lifecycle.
* Will be called when the resource is destroyed.
*/
public abstract destroy(): any;
/**
* Resource Settings Update Lifecycle.
* Called when the resource settings will to be updated.
* At this time, you can access the old settings through `this.resourceOption`.
*
* Note:
* You don't need to execute ```this.resourceOption = newResourceOption``` manually,
* The assignment will be done after this function returns.
* @param newResourceOption - New resource option.
*/
public abstract update(newResourceOption: ResourceOption): any;
}
@@ -0,0 +1,8 @@
/**
* Used to manage and process all GL resources.
* Rely on adding `ResourceHandler` to extend functions.
*/
class ResourcePool {
}
@@ -1,7 +1,22 @@
import { WebGLCanvas } from "state/WebGLCanvas";
import { WebGLState } from "state/WebGLState";
import type { WebGLCanvasOption } from "state/WebGLCanvas";
type WebGLRendererOption = WebGLCanvasOption;
class WebGLRenderer {
public constructor() {}
public canvas: WebGLCanvas;
public state: WebGLState;
public constructor(option: WebGLRendererOption) {
this.canvas = new WebGLCanvas(option);
this.state = new WebGLState();
this.state.bindCanvas(this.canvas);
}
}
export { WebGLRenderer };
@@ -1,5 +1,5 @@
import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer';
import { EventEmitter } from "./EventEmitter";
import { EventEmitter } from "kernel/EventEmitter";
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
@@ -61,7 +61,7 @@ type WebGLCanvasEventMap = {
class WebGLCanvas extends EventEmitter<WebGLCanvasEventMap> {
public readonly canvas: HTMLCanvasElement | OffscreenCanvas;
public readonly element: HTMLCanvasElement | OffscreenCanvas;
public readonly context: WebGLRenderingContext | WebGL2RenderingContext;
@@ -214,7 +214,7 @@ class WebGLCanvas extends EventEmitter<WebGLCanvasEventMap> {
}
}
this.canvas = targetCanvas;
this.element = targetCanvas;
this.context = targetContext;
this.glVersion = targetGLVersion;
this.isOffScreen = targetIsOffScreen;
@@ -238,12 +238,12 @@ class WebGLCanvas extends EventEmitter<WebGLCanvasEventMap> {
let hasResized = false;
if (width !== void 0) {
this.canvas.width = width;
this.element.width = width;
hasResized = true;
}
if (height !== void 0) {
this.canvas.height = height;
this.element.height = height;
hasResized = true;
}
@@ -280,8 +280,8 @@ class WebGLCanvas extends EventEmitter<WebGLCanvasEventMap> {
}
}
if (targetcontainer === null && this.canvas instanceof HTMLCanvasElement) {
targetcontainer = this.canvas.parentElement;
if (targetcontainer === null && this.element instanceof HTMLCanvasElement) {
targetcontainer = this.element.parentElement;
}
if (targetcontainer === null) {
@@ -307,11 +307,11 @@ class WebGLCanvas extends EventEmitter<WebGLCanvasEventMap> {
this.resizeObserver = resizeObserver;
if (this.canvas instanceof HTMLElement) {
this.canvas.style.width = "100%";
this.canvas.style.height = "100%";
this.canvas.style.boxSizing = "border-box";
this.canvas.style.display = "block";
if (this.element instanceof HTMLElement) {
this.element.style.width = "100%";
this.element.style.height = "100%";
this.element.style.boxSizing = "border-box";
this.element.style.display = "block";
}
resizeObserver.observe(targetcontainer);
@@ -0,0 +1,37 @@
import type { WebGLCanvas } from "./WebGLCanvas";
import { WebGLStateAbstract } from "./WebGLStateAbstract";
class WebGLState extends WebGLStateAbstract {
private statePool: Array<WebGLStateAbstract> = [];
private registerState(state: WebGLStateAbstract) {
this.statePool.push(state);
}
public override contextWillBind(newcanvas: WebGLCanvas) {
for (const state of this.statePool) {
state.bindCanvas(newcanvas);
}
}
public override contextLost() {
for (const state of this.statePool) {
state.contextLost();
}
}
public override resetState() {
for (const state of this.statePool) {
state.resetState();
}
}
public override destroy() {
for (const state of this.statePool) {
state.destroy();
}
}
}
export { WebGLState };
@@ -0,0 +1,56 @@
import type { WebGLCanvas } from "./WebGLCanvas";
/**
* Used for management, caching, encapsulation, WebGL context.
*/
abstract class WebGLStateAbstract {
private _canvas: WebGLCanvas | undefined;
/**
* binded canvas.
*/
public get canvas(): WebGLCanvas {
if (this._canvas) {
return this._canvas;
}
else {
throw new Error(
"[ray-lab WebGLStateBasic] Please get canvas instance after context binding."
);
}
};
/**
* Bind new WebGLCanvas.
*/
public bindCanvas(canvas: WebGLCanvas) {
this.contextWillBind(canvas);
this._canvas = canvas;
};
/**
* Life cycle hook function.
* Triggered when the context is rebound.
* @param newcanvas - New canvas object to be bound.
*/
public abstract contextWillBind(newcanvas: WebGLCanvas): any;
/**
* Life cycle hook function.
* Triggered when the context is lost.
*/
public abstract contextLost(): any;
/**
* Reset all states.
*/
public abstract resetState(): any;
/**
* Triggered when destroyed.
*/
public abstract destroy(): any;
}
export { WebGLStateAbstract };
@@ -1,3 +1,3 @@
export * from "kernel/WebGLCanvas";
export * from "state/WebGLCanvas";
export * from "kernel/EventEmitter";
export * from "renderer/WebGLRenderer";
+2 -1
View File
@@ -13,7 +13,8 @@
],
"paths": {
"kernel/*": ["./source/kernel/*"],
"renderer/*": ["./source/renderer/*"]
"renderer/*": ["./source/renderer/*"],
"state/*": ["./source/state/*"]
}
}
}