Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

asjs-dev/pwgl

Repository files navigation

A JavaScript framework for creating 2D WebGL2 applications

Game Demo

Demos:

Features:

  • Batch rendering (10.000 elements - 60fps)
  • Dynamic 2D lights and shadows
  • Element picker (can click on rendered items)
  • Image filters (Blur, Pixelate, Distortion, etc.)
  • Video textures
  • and many other features...

Minified version

How to use

Create your index html ( include pwgl.min.js )

<!DOCTYPE html>
<html>
 <head>
 <script src="pwgl.min.js" type="text/javascript"></script>
 </head>
 <body></body>
</html>

Add your script

class Application {
 constructor() {}
}
PWGL.Utils.initApplication(function (isWebGl2Supported) {
 if (!isWebGl2Supported) {
 // WebGL 2 is not supported
 return;
 }
 new Application();
});

Create a simple 2d renderer environment

class Application {
 constructor() {
 const width = 800;
 const height = 600;
 this._stageContainer = document.body;
 // create context
 this._context = new PWGL.Context();
 // create stage 2d renderer
 this._stage2DRenderer = new PWGL.Stage2D({
 config: {
 context: this._context,
 },
 });
 this._stageContainer.appendChild(this._context.canvas);
 // create renderable element
 this._image = new PWGL.Image(
 PWGL.Texture.loadImage("your/image/path/here")
 );
 this._image.transform.x = width * 0.5;
 this._image.transform.y = height * 0.5;
 this._image.transform.width = 320;
 this._image.transform.height = 240;
 this._image.transform.anchorX = this._image.transform.anchorY = 0.5;
 this._stage2DRenderer.container.addChild(this._image);
 // resize context and renderers
 this._context.setCanvasSize(width, height);
 this._stage2DRenderer.setSize(width, height);
 this._onBeforeUnloadBound = this._onBeforeUnload.bind(this);
 this._renderBound = this._render.bind(this);
 this._requestAnimationFrameId;
 window.addEventListener("beforeunload", this._onBeforeUnloadBound);
 // set fps meter
 PWGLExtensions.FPS.init();
 // start render cycle
 this._requestAnimationFrameId = requestAnimationFrame(this._renderBound);
 }
 _render() {
 if (this._requestAnimationFrameId) {
 PWGLExtensions.FPS.update();
 let delay = PWGLExtensions.FPS.delay;
 console.log("delay:", PWGLExtensions.FPS.delay);
 console.log("fps:", PWGLExtensions.FPS.fps.toFixed(2));
 // rotate the image
 this._image.transform.rotation += 0.001;
 // render the state
 this._stage2DRenderer.render();
 this._requestAnimationFrameId = requestAnimationFrame(this._renderBound);
 }
 }
 _destruct() {
 cancelAnimationFrame(this._requestAnimationFrameId);
 window.removeEventListener("beforeunload", this._onBeforeUnloadBound);
 this._stageContainer.removeChild(this._context.canvas);
 this._stage2DRenderer.destruct();
 }
 _onBeforeUnload() {
 this._destruct();
 }
}
PWGL.Utils.initApplication(function (isWebGl2Supported) {
 if (!isWebGl2Supported) {
 // WebGL 2 is not supported
 return;
 }
 new Application();
});

Add filter renderer

class Application {
 constructor() {
 const width = 800;
 const height = 600;
 this._stageContainer = document.body;
 // create context
 this._context = new PWGL.Context();
 // create framebuffer for the stage 2d renderer
 this._stage2DRendererFramebuffer = new PWGL.Framebuffer();
 // create stage 2d renderer
 this._stage2DRenderer = new PWGL.Stage2D({
 config: {
 context: this._context,
 },
 });
 // create filter renderer and set the framebuffer as texture source
 this._filterRenderer = new PWGL.FilterRenderer({
 config: {
 context: this._context,
 },
 sourceTexture: this._stage2DRendererFramebuffer,
 filters: [
 new PWGL.PixelateFilter(5),
 new PWGL.VignetteFilter(1, 3, 1, 0, 0, 0),
 ],
 });
 this._stageContainer.appendChild(this._context.canvas);
 // create renderable element
 this._image = new PWGL.Image(
 PWGL.Texture.loadImage("your/image/path/here")
 );
 this._image.transform.x = width * 0.5;
 this._image.transform.y = height * 0.5;
 this._image.transform.width = 320;
 this._image.transform.height = 240;
 this._image.transform.anchorX = this._image.transform.anchorY = 0.5;
 this._stage2DRenderer.container.addChild(this._image);
 // resize context and renderers
 this._context.setCanvasSize(width, height);
 this._stage2DRenderer.setSize(width, height);
 this._filterRenderer.setSize(width, height);
 this._onBeforeUnloadBound = this._onBeforeUnload.bind(this);
 this._renderBound = this._render.bind(this);
 this._requestAnimationFrameId;
 window.addEventListener("beforeunload", this._onBeforeUnloadBound);
 // set fps meter
 PWGLExtensions.FPS.init();
 // start render cycle
 this._requestAnimationFrameId = requestAnimationFrame(this._renderBound);
 }
 _render() {
 if (this._requestAnimationFrameId) {
 PWGLExtensions.FPS.update();
 let delay = PWGLExtensions.FPS.delay;
 console.log("delay:", PWGLExtensions.FPS.delay);
 console.log("fps:", PWGLExtensions.FPS.fps.toFixed(2));
 // rotate the image
 this._image.transform.rotation += 0.001;
 // render the state to framebuffer
 this._stage2DRenderer.renderToFramebuffer(
 this._stage2DRendererFramebuffer
 );
 // render filters
 this._filterRenderer.render();
 this._requestAnimationFrameId = requestAnimationFrame(this._renderBound);
 }
 }
 _destruct() {
 cancelAnimationFrame(this._requestAnimationFrameId);
 window.removeEventListener("beforeunload", this._onBeforeUnloadBound);
 this._stageContainer.removeChild(this._context.canvas);
 this._stage2DRenderer.destruct();
 this._filterRenderer.destruct();
 }
 _onBeforeUnload() {
 this._destruct();
 }
}
PWGL.Utils.initApplication(function (isWebGl2Supported) {
 if (!isWebGl2Supported) {
 // WebGL 2 is not supported
 return;
 }
 new Application();
});

AltStyle によって変換されたページ (->オリジナル) /