A JavaScript framework for creating 2D WebGL2 applications
- Top View Game Demo
- Card Game Demo
- Displacement Filter
- 2D Lights and Shadows
- Lights, Shadows and Filters
- Journey
- 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...
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(); });