The Wayback Machine - https://web.archive.org/web/20200913020216/https://github.com/coderitual/xna.js
Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
src
 
 
 
 
 
 
 
 
 
 

README.md

xna.js

This is the first public version of xna.js. WebGL library strongly inspired by XNA/Monogame framework. The library is in the early stages. I'm writing it because I want to learn WebGL and create some demo. Still a lot to do here.

Showcase:

Spritebatch

Normalmap

Mobile game

How to use:

lighting.js:

// Core
var Game = require("xnajs/game");
var Pointer = require("xnajs/input/pointer");
var Keyboard = require("xnajs/input/keyboard");
var Keys = require("xnajs/input/keys");

// Graphics
var Effect = require("xnajs/graphics/effect");
var SpriteBatch = require("xnajs/graphics/sprite-batch");
var VertexBuffer = require("xnajs/graphics/vertex-buffer");
var IndexBuffer = require("xnajs/graphics/index-buffer");
var Texture2d = require("xnajs/graphics/texture2d");
var Blend = require("xnajs/graphics/blend");
var BlendState = require("xnajs/graphics/blend-state");
var RenderTarget2D = require("xnajs/graphics/render-target2d");

// Components
var FpsMeter = require("xnajs-components/fps-meter");
var mat4 = require("xnajs/matrix/mat4");

var Lighting = Game.extend({
  initialize: function() {
    this.base();

    this.width = 1136;
    this.height = 640;

    this.graphicsDevice.backBufferWidth = this.width;
    this.graphicsDevice.backBufferHeight = this.height;

    Keyboard.addKey(Keys.SPACE);
    Keyboard.addKey(Keys.D);
    Keyboard.addKey(Keys.Q);
    Keyboard.addKey(Keys.W);
    Keyboard.addKey(Keys.A);
    Keyboard.addKey(Keys.S);

    this.debug = false;

    var ambient = 0.1;

    this._lights = [];
    this._ambientLight = [ambient, ambient, ambient, 1];
    this._specularStrength = 0.5;

    // add lights
    this._lights.push({
      color: [1.0, 0.0, 1.0, 1.0],
      power: 0.8,
      lightDecay: 400,
      position: [0, 0, 10],
      isEnabled: true
    });

    this._lights.push({
      color: [0.2, 0.4, 1.0, 1.0],
      power: 0.4,
      lightDecay: 300,
      position: [this.width / 2, 100, 10],
      isEnabled: true
    });

    this.newState = null;
    this.oldState = Keyboard.getState();
  },

  loadContent: function() {
    this.spriteBatch = new SpriteBatch(this.graphicsDevice);

    this.texture = this.content.load["Texture2D"](
      "textures/floor_tile_02-1024.jpg"
    );
    this.textureNormal = this.content.load["Texture2D"](
      "textures/floor_tile_02-1024_norm.jpg"
    );
    this.font = this.content.load["SpriteFont"]("fonts/quant.fnt");
    this.debugFont = this.content.load["SpriteFont"]("fonts/calibri16.fnt");

    this.width = this.graphicsDevice.backBufferWidth;
    this.height = this.graphicsDevice.backBufferHeight;

    this.colorMapRenderTarget = new RenderTarget2D(
      this.graphicsDevice,
      this.width,
      this.height
    );
    this.shadowMapRenderTarget = new RenderTarget2D(
      this.graphicsDevice,
      this.width,
      this.height
    );
    this.normalMapRenderTarget = new RenderTarget2D(
      this.graphicsDevice,
      this.width,
      this.height
    );

    this.pointLightEffect = new Effect(
      this.graphicsDevice,
      require("./shaders/deferred-pointlight.fx")
    );
    this.lightCombinedEffect = new Effect(
      this.graphicsDevice,
      require("./shaders/deferred-combined.fx")
    );

    this.fpsMeter = new FpsMeter();
  },

  update: function(gameTime) {
    // Tweak parameters

    this.newState = Keyboard.getState();

    // Is the SPACE key down?
    if (this.newState.isKeyDown(Keys.SPACE)) {
      //key has just been pressed.
      if (!this.oldState.isKeyDown(Keys.SPACE)) {
        this._lights.push({
          color: [Math.random(), Math.random(), Math.random(), 1.0],
          power: (Math.random() * 10 + 1) * 0.1,
          lightDecay: Math.random() * 300 + 100,
          position: [
            Math.random() * this.width,
            Math.random() * this.height,
            80
          ],
          isEnabled: true
        });
      }
    }

    // Is the SPACE key down?
    if (this.newState.isKeyDown(Keys.D)) {
      //key has just been pressed.
      if (!this.oldState.isKeyDown(Keys.D)) {
        this.debug = !this.debug;
      }
    }

    if (this.newState.isKeyDown(Keys.Q)) {
      var ambient = this._ambientLight[0];
      ambient -= 0.05;
      ambient = Math.max(0, ambient);
      this._ambientLight = [ambient, ambient, ambient, 1];
    }

    if (this.newState.isKeyDown(Keys.W)) {
      var ambient = this._ambientLight[0];
      ambient += 0.05;
      ambient = Math.min(1, ambient);
      this._ambientLight = [ambient, ambient, ambient, 1];
    }

    if (this.newState.isKeyDown(Keys.A)) {
      this._specularStrength -= 0.05;
      this._specularStrength = Math.max(0, this._specularStrength);
    }

    if (this.newState.isKeyDown(Keys.S)) {
      this._specularStrength += 0.05;
      this._specularStrength = Math.min(10, this._specularStrength);
    }

    // Update saved state.
    this.oldState = this.newState;

    this._lights[0].position[0] = Pointer.items[0].x;
    this._lights[0].position[1] = Pointer.items[0].y;

    light = this._lights[1];
    light.position[0] =
      Math.sin(gameTime.totalGameTime / 1000) * this.width / 4 + this.width / 2;
    light.position[1] =
      Math.cos(gameTime.totalGameTime / 1000) * this.height / 4 +
      this.height / 2;

    this.fpsMeter.update(gameTime);
  },

  draw: function(gameTime) {
    if (!this.content.isReady) {
      return;
    }

    this.graphicsDevice.clear([100 / 255, 149 / 255, 237 / 255, 1]);

    // Set the render targets
    this.graphicsDevice.setRenderTarget(this.colorMapRenderTarget);

    // Clear all render targets
    this.graphicsDevice.clear([0, 0, 0, 0]);

    this.drawColorMap();

    this.graphicsDevice.setRenderTarget(null);
    this.graphicsDevice.setRenderTarget(this.normalMapRenderTarget);

    // Clear all render targets
    this.graphicsDevice.clear([0, 0, 0, 0]);

    this.drawNormalMap();

    // Deactive the rander targets to resolve them
    this.graphicsDevice.setRenderTarget(null);

    this.generateShadowMap();

    this.graphicsDevice.clear([0, 0, 0, 1]);

    // Finally draw the combined Maps onto the screen
    this.drawCombinedMaps();

    this.drawDebugRenderTargets(this.spriteBatch);
    this.drawDebugInformation();
  },

  drawColorMap: function() {
    this.spriteBatch.begin();
    this.spriteBatch.draw(this.texture, [0, 0]);
    this.spriteBatch.end();
  },

  drawNormalMap: function() {
    this.spriteBatch.begin();
    this.spriteBatch.draw(this.textureNormal, [0, 0]);
    this.spriteBatch.end();
  },

  generateShadowMap: function() {
    this.graphicsDevice.setRenderTarget(this.shadowMapRenderTarget);
    this.graphicsDevice.clear([0, 0, 0, 1]);

    for (var i = 0; i < this._lights.length; i++) {
      var light = this._lights[i];

      if (!light.isEnabled) {
        continue;
      }

      this.pointLightEffect.apply();

      this.pointLightEffect.parameters["lightStrength"].setValue(light.power);
      this.pointLightEffect.parameters["lightPosition"].setValue(
        light.position
      );
      this.pointLightEffect.parameters["lightColor"].setValue(light.color);
      this.pointLightEffect.parameters["lightDecay"].setValue(light.lightDecay);
      this.pointLightEffect.parameters["specularStrength"].setValue(
        this._specularStrength
      );

      this.pointLightEffect.parameters["screenWidth"].setValue(this.width);
      this.pointLightEffect.parameters["screenHeight"].setValue(this.height);
      this.pointLightEffect.parameters["NormalMap"].setValue(
        this.normalMapRenderTarget
      );
      this.pointLightEffect.parameters["ColorMap"].setValue(
        this.colorMapRenderTarget
      );

      this.spriteBatch.begin(null, this.pointLightEffect);

      var gl = this.graphicsDevice.gl;
      gl.enable(gl.BLEND);
      gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.SRC_ALPHA, gl.ONE);
      gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);

      this.spriteBatch.draw(this.normalMapRenderTarget, [0, 0]);
      this.spriteBatch.end();
    }

    this.graphicsDevice.setRenderTarget(null);
  },

  drawCombinedMaps: function() {
    this.lightCombinedEffect.apply();
    this.lightCombinedEffect.parameters["ambient"].setValue(1);
    this.lightCombinedEffect.parameters["lightAmbient"].setValue(4);
    this.lightCombinedEffect.parameters["ambientColor"].setValue(
      this._ambientLight
    );
    this.lightCombinedEffect.parameters["NormalMap"].setValue(
      this.normalMapRenderTarget
    );
    this.lightCombinedEffect.parameters["ColorMap"].setValue(
      this.colorMapRenderTarget
    );
    this.lightCombinedEffect.parameters["ShadingMap"].setValue(
      this.shadowMapRenderTarget
    );

    this.spriteBatch.begin(Blend.ALPHA_BLEND, this.lightCombinedEffect);
    this.spriteBatch.draw(this.colorMapRenderTarget, [0, 0]);
    this.spriteBatch.end();
  },

  drawDebugRenderTargets: function(spriteBatch) {
    if (!this.debug) {
      return;
    }

    spriteBatch.begin();

    var scale = [1 / 3, 1 / 3];

    spriteBatch.draw(
      this.colorMapRenderTarget,
      [0, this.height - this.height / 3],
      null,
      null,
      0,
      scale,
      null
    );
    spriteBatch.draw(
      this.normalMapRenderTarget,
      [this.width / 3, this.height - this.height / 3],
      null,
      null,
      0,
      scale,
      null
    );
    spriteBatch.draw(
      this.shadowMapRenderTarget,
      [this.width / 3 * 2, this.height - this.height / 3],
      null,
      null,
      0,
      scale,
      null
    );

    spriteBatch.end();
  },

  drawDebugInformation: function() {
    var lines = [
      "xna.js",
      "fps: " + this.fpsMeter.fps,
      "x: " + Pointer.items[0].x + ", y: " + Pointer.items[0].y,
      "lights: " + this._lights.length,
      "Press SPACE to add light",
      "Press D to toggle debug",
      "Q,W: Ambient light: " + this._ambientLight[0].toPrecision(2),
      "A,S: Specular strength: " + this._specularStrength.toPrecision(2)
    ];

    this.spriteBatch.begin();

    for (var i = 0; i < lines.length; i++) {
      this.spriteBatch.drawString(this.debugFont, lines[i], [
        10,
        10 + this.debugFont.lineHeight * i
      ]);
    }

    this.spriteBatch.end();
  }
});

main.js:

var Lighting = require('./lighting');

document.addEventListener('DOMContentLoaded', main, false);
function main() {
    var game = new Lighting('#game');
    game.run();
}

License

Xna.js is available under the MIT license. See the LICENSE file for more info.

About

WebGL framework strongly inspired by the XNA library

Topics

Resources

License

Releases

No releases published

Packages

No packages published
You can’t perform that action at this time.