Skip to content
Browse files

adds support for highDPI devices

  • Loading branch information...
1 parent e417fc7 commit 13d288fc0744156f1e289fb76517c3d022d01a79 @funkaster committed Nov 5, 2012
View
11 chesterGL/block.js
@@ -398,7 +398,13 @@ chesterGL.Block.prototype.setFrame = function (newFrame) {
} else {
goog.vec.Vec4.setFromArray(this.frame, newFrame);
}
- this.setContentSize(newFrame[2], newFrame[3]);
+ // if on highDPI mode, and the texture is a highDPI texture, then set the content size to the
+ // "real" content size.
+ if (chesterGL.highDPI && this.texture && chesterGL.assets['texture'][this.texture].highDPI) {
+ this.setContentSize(newFrame[2] / chesterGL.devicePixelRatio, newFrame[3] / chesterGL.devicePixelRatio);
+ } else {
+ this.setContentSize(newFrame[2], newFrame[3]);
+ }
this.isFrameDirty = true;
};
@@ -596,9 +602,6 @@ chesterGL.Block.prototype.setTexture = function (texturePath) {
var block = this;
chesterGL.loadAsset("texture", texturePath, null, function (t) {
// set the default frame for all our blocks (if it's not set)
- if (!block.contentSize) {
- block.setContentSize(t.width, t.height);
- }
if (!block.frame) {
block.setFrame([0, 0, t.width, t.height]);
}
View
104 chesterGL/core.js
@@ -38,18 +38,19 @@ HTMLCanvasElement._canvas_tmp_mouse = new goog.math.Vec2(0, 0);
* @return {goog.math.Vec2}
*/
HTMLCanvasElement.prototype.relativePosition = function (evt) {
- var pt = HTMLCanvasElement._canvas_tmp_mouse;
+ var pt = HTMLCanvasElement._canvas_tmp_mouse,
+ height = (chesterGL.highDPI ? this.height / chesterGL.devicePixelRatio : this.height);
pt.x = 0; pt.y = 0;
if (typeof this['__offset'] === "undefined") {
this['__offset'] = $(this).offset();
}
if (evt.changedTouches) {
var t = evt.changedTouches[0];
pt.x = (t.pageX - this['__offset'].left);
- pt.y = (this.height - (t.pageY - this['__offset'].top));
+ pt.y = (height - (t.pageY - this['__offset'].top));
} else {
pt.x = (evt.pageX - this['__offset'].left);
- pt.y = (this.height - (evt.pageY - this['__offset'].top));
+ pt.y = (height - (evt.pageY - this['__offset'].top));
}
return pt;
@@ -244,6 +245,12 @@ chesterGL.canvas = null;
chesterGL.debugSprite = false;
/**
+ * Whether or not we're running on a highDPI device
+ * @type {boolean}
+ */
+chesterGL.highDPI = false;
+
+/**
* @type {Object.<string,Object>}
* @ignore
*/
@@ -394,7 +401,26 @@ chesterGL.setup = function (canvasId) {
* @param {Element} canvas
*/
chesterGL.initGraphics = function (canvas) {
+ var desiredWidth = 0,
+ desiredHeight = 0;
try {
+ // test for high-dpi device
+ if (window.devicePixelRatio && window.devicePixelRatio > 1) {
+ var devicePixelRatio = window.devicePixelRatio;
+ console.log("using HighDPI resolution (devicePixelRatio: " + devicePixelRatio + ")");
+ desiredWidth = canvas.width;
+ desiredHeight = canvas.height;
+ canvas.style.width = canvas.width + "px";
+ canvas.style.height = canvas.height + "px";
+ canvas.width = canvas.clientWidth * devicePixelRatio;
+ canvas.height = canvas.clientHeight * devicePixelRatio;
+ chesterGL.highDPI = true;
+ chesterGL.devicePixelRatio = window.devicePixelRatio;
+ } else {
+ desiredWidth = canvas.width;
+ desiredHeight = canvas.height;
+ }
+
chesterGL.canvas = canvas;
if (chesterGL.webglMode) {
chesterGL.gl = canvas.getContext("experimental-webgl", {alpha: false, antialias: false, preserveDrawingBuffer: true});
@@ -409,23 +435,15 @@ chesterGL.initGraphics = function (canvas) {
if (!chesterGL.gl) {
// fallback to canvas API (uses an offscreen buffer)
chesterGL.gl = canvas.getContext("2d");
- if (chesterGL.usesOffscreenBuffer) {
- chesterGL.offCanvas = document.createElement('canvas');
- chesterGL.offCanvas.width = canvas.width;
- chesterGL.offCanvas.height = canvas.height;
- chesterGL.offContext = chesterGL.offCanvas.getContext("2d");
- chesterGL.offContext.viewportWidth = canvas.width;
- chesterGL.offContext.viewportHeight = canvas.height;
- } else {
- chesterGL.offContext = chesterGL.gl;
- }
- if (!chesterGL.gl || !chesterGL.offContext) {
+ if (!chesterGL.gl) {
throw "Error initializing graphic context!";
}
chesterGL.webglMode = chesterGL.settings['webglMode'] = false;
}
+
// first resize of the canvas
- chesterGL.canvasResized();
+ chesterGL.gl.viewportWidth = desiredWidth;
+ chesterGL.gl.viewportHeight = desiredHeight;
// install touch handler
chesterGL.installMouseHandlers();
@@ -613,7 +631,8 @@ chesterGL.loadAsset = function (type, url, name, callback) {
params = {
dataType: url.dataType,
url: url.url,
- name: url.name || url.url
+ name: url.name || url.url,
+ forceNonRetina: url.forceNonRetina || false
};
} else {
params = {
@@ -626,6 +645,17 @@ chesterGL.loadAsset = function (type, url, name, callback) {
chesterGL.assets[type] = {};
}
+ // test for explicit @Nx request, if no such request, then add the @Nx prefix *only* if on
+ // highDPI mode
+ var md,
+ re = new RegExp("@" + chesterGL.devicePixelRatio + "x\\..+$");
+ if (chesterGL.highDPI && !params.forceNonRetina && (md = params.url.match(re)) === null) {
+ md = params.url.match(/(\..+$)/);
+ if (md && chesterGL.highDPI) {
+ params.url = params.url.replace(/(\..+$)/, "@" + chesterGL.devicePixelRatio + "x$1");
+ }
+ }
+
var assets = chesterGL.assets[type],
rname = params.name;
if (!assets[rname]) {
@@ -803,27 +833,41 @@ chesterGL.defaultTextureHandler = function (params, img, type) {
chesterGL.defaultTextureLoader = function (type, params) {
var img = new Image(),
path = params.url,
- name = params.name;
+ name = params.name,
+ re = new RegExp("@" + chesterGL.devicePixelRatio + "x\\..+$");
+
img.src = "";
img.addEventListener("load", function () {
var texture = chesterGL.assets['texture'][name];
if (chesterGL.assetsHandlers[type](params, img)) {
// call all listeners
- texture.status = 'loaded';
+ texture.status = "loaded";
+ texture.highDPI = path.match(re) && chesterGL.highDPI;
var l;
while ((l = texture.listeners.shift())) { l(texture.data); }
// test for assets loaded
chesterGL.assetsLoaded(type);
- chesterGL.assetsLoaded('all');
+ chesterGL.assetsLoaded("all");
} else {
// requeue
- texture.status = 'try';
+ texture.status = "try";
chesterGL.loadAsset(type, params);
}
}, false);
+ img.addEventListener("error", function (e) {
+ // if we're a highDPI image, and we failed, load again without @Nx
+ if (e.type === "error" && chesterGL.highDPI && path.match(re)) {
+ var texture = chesterGL.assets["texture"][name];
+ params.url = path.replace("@" + chesterGL.devicePixelRatio + "x", "");
+ params.forceNonRetina = true;
+ // requeue
+ texture.status = "try";
+ chesterGL.loadAsset("texture", params);
+ }
+ }, true);
// append the basePath if it's not an absolute url or a data:image url
if (path.match(/^http(s)?:/)) {
- img.crossOrigin = 'anonymous';
+ img.crossOrigin = "anonymous";
img.src = path;
} else if (path.match(/^data:/)) {
img.src = path;
@@ -840,16 +884,18 @@ chesterGL.defaultTextureLoader = function (type, params) {
chesterGL.defaultAssetLoader = function (type, params) {
var path = params.url,
realPath = path,
- name = params.name;
+ name = params.name,
+ re = new RegExp("@" + chesterGL.devicePixelRatio + "x\\..+$");
+
if (!path.match(/^http(s)?:\/\//)) {
realPath = chesterGL.basePath + path;
}
var req = new XMLHttpRequest();
req.open("GET", realPath);
req.withCredentials = true;
req.onreadystatechange = function () {
+ var asset = chesterGL.assets[type][name];
if (req.readyState == 4 && req.status == 200) {
- var asset = chesterGL.assets[type][name];
var handler = chesterGL.assetsHandlers[type] || chesterGL.assetsHandlers['default'];
if (handler(params, req.response, type)) {
asset.status = 'loaded';
@@ -865,7 +911,15 @@ chesterGL.defaultAssetLoader = function (type, params) {
chesterGL.loadAsset(type, params);
}
} else if (req.readyState == 4) {
- console.log("Error loading asset " + path);
+ if (req.status == 404 && chesterGL.highDPI && path.match(re)) {
+ params.url = path.replace("@" + chesterGL.devicePixelRatio + "x", "");
+ params.forceNonRetina = true;
+ // requeue
+ asset.status = "try";
+ chesterGL.loadAsset(type, params);
+ } else {
+ console.log("Error loading asset " + path);
+ }
}
};
req.send();
@@ -893,7 +947,7 @@ chesterGL.setupPerspective = function () {
var width = gl.viewportWidth;
var height = gl.viewportHeight;
- gl.viewport(0, 0, width, height);
+ gl.viewport(0, 0, chesterGL.canvas.width, chesterGL.canvas.height);
chesterGL.pMatrix = goog.vec.Mat4.createFloat32();
View
BIN html/images/ship.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN html/images/ship@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN html/images/ship_non_hdpi.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
1 html/index.html
@@ -39,6 +39,7 @@
<li><a href="test_base64_texture.html">Textures as Base64</a>: tests textures encoded inline in base64</li>
<li><a href="test_requirejs.html">require.js</a>: testing integration with <a href="http://requirejs.org/">require.js</a></li>
<li><a href="test_to_local.html">toLocal</a>: tests the conversion from global to local space</li>
+ <li><a href="test_high_dpi.html">highDPI</a>: simple test to showcase the highDPI support</li>
</ul>
</body>
</html>
View
70 html/test_high_dpi.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="test.css"/>
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
+ <!-- <script type="text/javascript" src="externals/webgl-debug.js"></script> -->
+ <script src="http://commondatastorage.googleapis.com/chestergl/Stats.js"></script>
+ <script type="text/javascript" src="chester.js"></script>
+ <!-- audio!! -->
+ <script type="text/javascript">
+
+$(document).ready(function () {
+ setupGame();
+ function setupGame() {
+ chesterGL.settings['useGoogleAnalytics'] = true;
+ chesterGL.setup("demo-canvas");
+ var size = chesterGL.viewportSize();
+ var oneDeg = Math.PI / 180.0;
+
+ chesterGL.loadAsset("texture", "images/ship.png");
+ chesterGL.loadAsset("texture", "images/ship_non_hdpi.png");
+ chesterGL.assetsLoaded("texture", function () {
+ // $("#loading").html("Test Single Block");
+ // finish with the setup and run the game
+ chesterGL.setupPerspective();
+
+ var sceneBlock = new chesterGL.Block(null, chesterGL.Block.TYPE['SCENE']);
+ sceneBlock.title = "Test::HighDPI";
+ chesterGL.setRunningScene(sceneBlock);
+
+ // create a block
+ var retinaShip = new chesterGL.Block();
+ retinaShip.setTexture("images/ship.png")
+ // someBlock.rotateBy(-45);
+ retinaShip.setPosition(size.width/2 - 100, size.height/2, 0);
+
+ var nonRetinaShip = new chesterGL.Block();
+ nonRetinaShip.setTexture("images/ship_non_hdpi.png");
+ nonRetinaShip.setPosition(size.width/2 + 100, size.height/2, 0);
+
+ sceneBlock.addChild(retinaShip, nonRetinaShip);
+
+ chesterGL.run();
+ // draw a single frame (for debug purposes)
+ // chesterGL.drawScene();
+ });
+ } // setupGame()
+});
+ </script>
+ <script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-77863-9']);
+_gaq.push(['_trackPageview']);
+
+(function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+ </script>
+</head>
+<body>
+ <div id="loading" style="position: absolute; z-index: 100;"></div>
+ <div id="game-container">
+ <canvas id="demo-canvas" width="640" height="480"></canvas>
+ <div>
+ </div>
+ </div>
+</body>
+</html>

0 comments on commit 13d288f

Please sign in to comment.
Something went wrong with that request. Please try again.