ruby2d 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/assets/opal.js +42 -42
- data/assets/simple2d.js +422 -223
- data/bin/ruby2d +26 -24
- data/ext/ruby2d/extconf.rb +6 -6
- data/ext/ruby2d/ruby2d-opal.rb +133 -69
- data/ext/ruby2d/ruby2d.c +246 -114
- data/lib/ruby2d/application.rb +14 -18
- data/lib/ruby2d/color.rb +50 -12
- data/lib/ruby2d/dsl.rb +12 -16
- data/lib/ruby2d/exceptions.rb +0 -9
- data/lib/ruby2d/image.rb +25 -28
- data/lib/ruby2d/line.rb +64 -0
- data/lib/ruby2d/music.rb +30 -5
- data/lib/ruby2d/quad.rb +52 -44
- data/lib/ruby2d/rectangle.rb +24 -13
- data/lib/ruby2d/renderable.rb +35 -0
- data/lib/ruby2d/sound.rb +15 -5
- data/lib/ruby2d/sprite.rb +21 -19
- data/lib/ruby2d/square.rb +14 -9
- data/lib/ruby2d/text.rb +36 -32
- data/lib/ruby2d/triangle.rb +46 -44
- data/lib/ruby2d/version.rb +1 -1
- data/lib/ruby2d/window.rb +148 -120
- data/lib/ruby2d.rb +2 -0
- metadata +5 -3
data/assets/simple2d.js
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
// Simple2D.js — v0.
|
1
|
+
// Simple2D.js — v0.2.0, built 06-04-2017
|
2
2
|
|
3
3
|
// start.js - Open the anonymous function defining the Simple 2D module
|
4
4
|
|
5
5
|
(function(undefined) {
|
6
|
-
|
6
|
+
|
7
7
|
// Check if Simple 2D is already loaded
|
8
8
|
if (typeof(this.S2D) !== 'undefined') {
|
9
9
|
console.warn("Simple 2D already loaded! Loading twice may cause problems.");
|
10
10
|
return this.S2D;
|
11
11
|
}
|
12
|
-
|
12
|
+
|
13
13
|
// Create the Simple 2D module
|
14
14
|
var S2D = this.S2D = {};
|
15
|
-
|
15
|
+
|
16
16
|
// ... Simple 2D library starts here ...
|
17
17
|
|
18
18
|
|
@@ -21,16 +21,42 @@
|
|
21
21
|
// Simple 2D OpenGL namespace
|
22
22
|
S2D.GL = {};
|
23
23
|
|
24
|
-
// Simple 2D definitions
|
25
|
-
Object.defineProperty(S2D, "KEYDOWN", { value: 1 });
|
26
|
-
Object.defineProperty(S2D, "KEY", { value: 2 });
|
27
|
-
Object.defineProperty(S2D, "KEYUP", { value: 3 });
|
28
|
-
|
29
24
|
// Viewport scaling modes
|
30
25
|
Object.defineProperty(S2D, "FIXED", { value: 1 });
|
31
26
|
Object.defineProperty(S2D, "SCALE", { value: 2 });
|
32
27
|
Object.defineProperty(S2D, "STRETCH", { value: 3 });
|
33
28
|
|
29
|
+
// Keyboard events
|
30
|
+
Object.defineProperty(S2D, "KEY_DOWN", { value: 1 });
|
31
|
+
Object.defineProperty(S2D, "KEY_HELD", { value: 2 });
|
32
|
+
Object.defineProperty(S2D, "KEY_UP", { value: 3 });
|
33
|
+
|
34
|
+
// Mouse events
|
35
|
+
Object.defineProperty(S2D, "MOUSE_DOWN", { value: 1 });
|
36
|
+
Object.defineProperty(S2D, "MOUSE_UP", { value: 2 });
|
37
|
+
Object.defineProperty(S2D, "MOUSE_SCROLL", { value: 3 });
|
38
|
+
Object.defineProperty(S2D, "MOUSE_MOVE", { value: 4 });
|
39
|
+
Object.defineProperty(S2D, "MOUSE_LEFT", { value: 5 });
|
40
|
+
Object.defineProperty(S2D, "MOUSE_MIDDLE", { value: 6 });
|
41
|
+
Object.defineProperty(S2D, "MOUSE_RIGHT", { value: 7 });
|
42
|
+
Object.defineProperty(S2D, "MOUSE_X1", { value: 8 });
|
43
|
+
Object.defineProperty(S2D, "MOUSE_X2", { value: 9 });
|
44
|
+
Object.defineProperty(S2D, "MOUSE_SCROLL_NORMAL", { value: 10 });
|
45
|
+
Object.defineProperty(S2D, "MOUSE_SCROLL_INVERTED", { value: 11 });
|
46
|
+
|
47
|
+
// Event
|
48
|
+
S2D.Event = {
|
49
|
+
which: null,
|
50
|
+
type: null,
|
51
|
+
button: null,
|
52
|
+
key: null,
|
53
|
+
x: 0,
|
54
|
+
y: 0,
|
55
|
+
delta_x: 0,
|
56
|
+
delta_y: 0,
|
57
|
+
direction: null
|
58
|
+
};
|
59
|
+
|
34
60
|
// Color
|
35
61
|
S2D.Color = {
|
36
62
|
r: 1.0,
|
@@ -56,7 +82,9 @@ S2D.Window = {
|
|
56
82
|
render: null,
|
57
83
|
mouse: {
|
58
84
|
x: 0,
|
59
|
-
y: 0
|
85
|
+
y: 0,
|
86
|
+
last_x: 0,
|
87
|
+
last_y: 0
|
60
88
|
},
|
61
89
|
on_key: null,
|
62
90
|
on_mouse: null,
|
@@ -83,10 +111,13 @@ S2D.Image = {
|
|
83
111
|
// Sprite
|
84
112
|
S2D.Sprite = {
|
85
113
|
img: null,
|
114
|
+
color: null,
|
86
115
|
x: 0,
|
87
116
|
y: 0,
|
88
117
|
width: null,
|
89
118
|
height: null,
|
119
|
+
clip_width: null,
|
120
|
+
clip_height: null,
|
90
121
|
tx1: null,
|
91
122
|
ty1: null,
|
92
123
|
tx2: null,
|
@@ -130,27 +161,27 @@ S2D.keys_down = [];
|
|
130
161
|
// On keyboard starting at top row, left to right
|
131
162
|
S2D.key_map = {
|
132
163
|
27: "Escape",
|
133
|
-
|
164
|
+
|
134
165
|
192: "`",
|
135
166
|
189: "-",
|
136
167
|
187: "=",
|
137
168
|
8: "Backspace",
|
138
|
-
|
169
|
+
|
139
170
|
9: "Tab",
|
140
171
|
219: "[",
|
141
172
|
221: "]",
|
142
173
|
220: "\\",
|
143
|
-
|
174
|
+
|
144
175
|
20: "CapsLock",
|
145
176
|
186: ";",
|
146
177
|
222: "'",
|
147
178
|
13: "Return",
|
148
|
-
|
179
|
+
|
149
180
|
16: "Shift",
|
150
181
|
188: ",",
|
151
182
|
190: ".",
|
152
183
|
191: "/",
|
153
|
-
|
184
|
+
|
154
185
|
17: "Ctrl",
|
155
186
|
18: "Option",
|
156
187
|
91: "Left Command",
|
@@ -190,28 +221,28 @@ S2D.TrimCanvas = function(c) {
|
|
190
221
|
bottom: null
|
191
222
|
},
|
192
223
|
x, y;
|
193
|
-
|
224
|
+
|
194
225
|
for (i = 0; i < l; i += 4) {
|
195
226
|
if (pixels.data[i+3] !== 0) {
|
196
227
|
x = (i / 4) % c.width;
|
197
228
|
y = ~~((i / 4) / c.width);
|
198
|
-
|
229
|
+
|
199
230
|
if (bound.top === null) {
|
200
231
|
bound.top = y;
|
201
232
|
}
|
202
|
-
|
233
|
+
|
203
234
|
if (bound.left === null) {
|
204
235
|
bound.left = x;
|
205
236
|
} else if (x < bound.left) {
|
206
237
|
bound.left = x;
|
207
238
|
}
|
208
|
-
|
239
|
+
|
209
240
|
if (bound.right === null) {
|
210
241
|
bound.right = x;
|
211
242
|
} else if (bound.right < x) {
|
212
243
|
bound.right = x;
|
213
244
|
}
|
214
|
-
|
245
|
+
|
215
246
|
if (bound.bottom === null) {
|
216
247
|
bound.bottom = y;
|
217
248
|
} else if (bound.bottom < y) {
|
@@ -219,54 +250,141 @@ S2D.TrimCanvas = function(c) {
|
|
219
250
|
}
|
220
251
|
}
|
221
252
|
}
|
222
|
-
|
253
|
+
|
223
254
|
var trimHeight = bound.bottom - bound.top,
|
224
255
|
trimWidth = bound.right - bound.left,
|
225
256
|
trimmed = ctx.getImageData(bound.left, bound.top, trimWidth, trimHeight);
|
226
|
-
|
257
|
+
|
227
258
|
copy.canvas.width = trimWidth;
|
228
259
|
copy.canvas.height = trimHeight;
|
229
260
|
copy.putImageData(trimmed, 0, 0);
|
230
|
-
|
261
|
+
|
231
262
|
// open new window with trimmed image:
|
232
263
|
return copy.canvas;
|
233
264
|
};
|
234
265
|
|
266
|
+
// Creates a global "addWheelListener" method
|
267
|
+
// example: addWheelListener(el, function(e) { console.log(e.deltaY); e.preventDefault(); });
|
268
|
+
// Adapted from: https://developer.mozilla.org/en-US/docs/Web/Events/wheel
|
269
|
+
(function(window, document) {
|
270
|
+
|
271
|
+
var prefix = "",
|
272
|
+
_addEventListener, support;
|
273
|
+
|
274
|
+
// detect event model
|
275
|
+
if (window.addEventListener) {
|
276
|
+
_addEventListener = "addEventListener";
|
277
|
+
} else {
|
278
|
+
_addEventListener = "attachEvent";
|
279
|
+
prefix = "on";
|
280
|
+
}
|
281
|
+
|
282
|
+
// detect available wheel event
|
283
|
+
support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
|
284
|
+
document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
|
285
|
+
"DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
|
286
|
+
|
287
|
+
window.addWheelListener = function(elem, callback, useCapture) {
|
288
|
+
_addWheelListener(elem, support, callback, useCapture);
|
289
|
+
|
290
|
+
// handle MozMousePixelScroll in older Firefox
|
291
|
+
if (support == "DOMMouseScroll") {
|
292
|
+
_addWheelListener(elem, "MozMousePixelScroll", callback, useCapture);
|
293
|
+
}
|
294
|
+
};
|
295
|
+
|
296
|
+
function _addWheelListener(elem, eventName, callback, useCapture) {
|
297
|
+
elem[_addEventListener](prefix + eventName, support == "wheel" ? callback : function(originalEvent) {
|
298
|
+
!originalEvent && (originalEvent = window.event);
|
299
|
+
|
300
|
+
// create a normalized event object
|
301
|
+
var event = {
|
302
|
+
// keep a ref to the original event object
|
303
|
+
originalEvent: originalEvent,
|
304
|
+
target: originalEvent.target || originalEvent.srcElement,
|
305
|
+
type: "wheel",
|
306
|
+
deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
|
307
|
+
deltaX: 0,
|
308
|
+
deltaY: 0,
|
309
|
+
deltaZ: 0,
|
310
|
+
preventDefault: function() {
|
311
|
+
originalEvent.preventDefault ?
|
312
|
+
originalEvent.preventDefault() :
|
313
|
+
originalEvent.returnValue = false;
|
314
|
+
}
|
315
|
+
};
|
316
|
+
|
317
|
+
// calculate deltaY (and deltaX) according to the event
|
318
|
+
if (support == "mousewheel") {
|
319
|
+
event.deltaY = -1 / 40 * originalEvent.wheelDelta;
|
320
|
+
// Webkit also support wheelDeltaX
|
321
|
+
originalEvent.wheelDeltaX && (event.deltaX = -1 / 40 * originalEvent.wheelDeltaX);
|
322
|
+
} else {
|
323
|
+
event.deltaY = originalEvent.detail;
|
324
|
+
}
|
325
|
+
|
326
|
+
// it's time to fire the callback
|
327
|
+
return callback(event);
|
328
|
+
|
329
|
+
}, useCapture || false);
|
330
|
+
}
|
331
|
+
|
332
|
+
})(window, document);
|
333
|
+
|
235
334
|
|
236
335
|
// shapes.js
|
237
336
|
|
238
337
|
/*
|
239
338
|
* Draw a triangle
|
240
339
|
*/
|
241
|
-
S2D.DrawTriangle = function(x1, y1,
|
242
|
-
x2, y2,
|
243
|
-
x3, y3,
|
244
|
-
|
245
|
-
S2D.GL.DrawTriangle(x1, y1,
|
246
|
-
x2, y2,
|
247
|
-
x3, y3,
|
340
|
+
S2D.DrawTriangle = function(x1, y1, r1, g1, b1, a1,
|
341
|
+
x2, y2, r2, g2, b2, a2,
|
342
|
+
x3, y3, r3, g3, b3, a3) {
|
343
|
+
|
344
|
+
S2D.GL.DrawTriangle(x1, y1, r1, g1, b1, a1,
|
345
|
+
x2, y2, r2, g2, b2, a2,
|
346
|
+
x3, y3, r3, g3, b3, a3);
|
248
347
|
};
|
249
348
|
|
250
349
|
|
251
350
|
/*
|
252
351
|
* Draw a quad, using two triangles
|
253
352
|
*/
|
254
|
-
S2D.DrawQuad = function(x1,
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
S2D.GL.DrawTriangle(
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
353
|
+
S2D.DrawQuad = function(x1, y1, r1, g1, b1, a1,
|
354
|
+
x2, y2, r2, g2, b2, a2,
|
355
|
+
x3, y3, r3, g3, b3, a3,
|
356
|
+
x4, y4, r4, g4, b4, a4) {
|
357
|
+
|
358
|
+
S2D.GL.DrawTriangle(x1, y1, r1, g1, b1, a1,
|
359
|
+
x2, y2, r2, g2, b2, a2,
|
360
|
+
x3, y3, r3, g3, b3, a3);
|
361
|
+
|
362
|
+
S2D.GL.DrawTriangle(x3, y3, r3, g3, b3, a3,
|
363
|
+
x4, y4, r4, g4, b4, a4,
|
364
|
+
x1, y1, r1, g1, b1, a1);
|
365
|
+
};
|
366
|
+
|
367
|
+
|
368
|
+
/*
|
369
|
+
* Draw a line from a quad
|
370
|
+
*/
|
371
|
+
S2D.DrawLine = function(x1, y1, x2, y2,
|
372
|
+
width,
|
373
|
+
r1, g1, b1, a1,
|
374
|
+
r2, g2, b2, a2,
|
375
|
+
r3, g3, b3, a3,
|
376
|
+
r4, g4, b4, a4) {
|
377
|
+
|
378
|
+
var length = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
|
379
|
+
var x = ((x2 - x1) / length) * width / 2;
|
380
|
+
var y = ((y2 - y1) / length) * width / 2;
|
381
|
+
|
382
|
+
S2D.DrawQuad(
|
383
|
+
x1 - y, y1 + x, r1, g1, b1, a1,
|
384
|
+
x1 + y, y1 - x, r2, g2, b2, a2,
|
385
|
+
x2 + y, y2 - x, r3, g3, b3, a3,
|
386
|
+
x2 - y, y2 + x, r4, g4, b4, a4
|
387
|
+
);
|
270
388
|
};
|
271
389
|
|
272
390
|
|
@@ -277,24 +395,24 @@ S2D.DrawQuad = function(x1, y1,
|
|
277
395
|
* Params: path = image file path
|
278
396
|
*/
|
279
397
|
S2D.CreateImage = function(path, loadedCallback) {
|
280
|
-
|
398
|
+
|
281
399
|
// TODO: Check if image file exists
|
282
|
-
|
400
|
+
|
283
401
|
// Create image object
|
284
402
|
var img = Object.create(S2D.Image);
|
285
403
|
img.data = new Image();
|
286
404
|
img.color = Object.create(S2D.Color);
|
287
|
-
|
405
|
+
|
288
406
|
img.data.onload = function() {
|
289
407
|
img.texture = S2D.GL.CreateTexture(this);
|
290
|
-
if (!img.width)
|
408
|
+
if (!img.width ) img.width = this.width;
|
291
409
|
if (!img.height) img.height = this.height;
|
292
410
|
if (loadedCallback) loadedCallback();
|
293
411
|
};
|
294
|
-
|
412
|
+
|
295
413
|
// Causes image to be loaded
|
296
414
|
img.data.src = path;
|
297
|
-
|
415
|
+
|
298
416
|
return img;
|
299
417
|
};
|
300
418
|
|
@@ -314,15 +432,18 @@ S2D.DrawImage = function(img) {
|
|
314
432
|
* Create a sprite, given an image file path
|
315
433
|
*/
|
316
434
|
S2D.CreateSprite = function(path) {
|
317
|
-
|
435
|
+
|
318
436
|
// TODO: Check if sprite image file exists
|
319
|
-
|
437
|
+
|
320
438
|
var spr = Object.create(S2D.Sprite);
|
439
|
+
spr.color = Object.create(S2D.Color);
|
321
440
|
spr.img = S2D.CreateImage(path, function() {
|
322
|
-
spr.width = spr.img.width;
|
323
|
-
spr.height = spr.img.height;
|
441
|
+
if (!spr.width ) spr.width = spr.img.width;
|
442
|
+
if (!spr.height) spr.height = spr.img.height;
|
443
|
+
spr.clip_width = spr.img.width;
|
444
|
+
spr.clip_height = spr.img.height;
|
324
445
|
});
|
325
|
-
|
446
|
+
|
326
447
|
spr.tx1 = 0.0;
|
327
448
|
spr.ty1 = 0.0;
|
328
449
|
spr.tx2 = 1.0;
|
@@ -331,7 +452,7 @@ S2D.CreateSprite = function(path) {
|
|
331
452
|
spr.ty3 = 1.0;
|
332
453
|
spr.tx4 = 0.0;
|
333
454
|
spr.ty4 = 1.0;
|
334
|
-
|
455
|
+
|
335
456
|
return spr;
|
336
457
|
};
|
337
458
|
|
@@ -341,44 +462,46 @@ S2D.CreateSprite = function(path) {
|
|
341
462
|
*/
|
342
463
|
S2D.ClipSprite = function(spr, x, y, w, h) {
|
343
464
|
if (!spr) return;
|
344
|
-
|
465
|
+
|
345
466
|
// Calculate ratios
|
346
467
|
// rw = ratio width; rh = ratio height
|
347
468
|
var rw = w / spr.img.width;
|
348
469
|
var rh = h / spr.img.height;
|
349
|
-
|
470
|
+
|
350
471
|
// Apply ratios to x, y coordinates
|
351
472
|
// cx = crop x coord; cy = crop y coord
|
352
473
|
var cx = x * rw;
|
353
474
|
var cy = y * rh;
|
354
|
-
|
475
|
+
|
355
476
|
// Convert given width, height to doubles
|
356
477
|
// cw = crop width; ch = crop height
|
357
478
|
var cw = w;
|
358
479
|
var ch = h;
|
359
|
-
|
480
|
+
|
360
481
|
// Apply ratio to texture width and height
|
361
482
|
// tw = texture width; th = texture height
|
362
483
|
var tw = rw * w;
|
363
484
|
var th = rh * h;
|
364
|
-
|
485
|
+
|
365
486
|
// Calculate and store sprite texture values
|
366
|
-
|
487
|
+
|
367
488
|
spr.tx1 = cx / cw;
|
368
489
|
spr.ty1 = cy / ch;
|
369
|
-
|
490
|
+
|
370
491
|
spr.tx2 = (cx + tw) / cw;
|
371
492
|
spr.ty2 = cy / ch;
|
372
|
-
|
493
|
+
|
373
494
|
spr.tx3 = (cx + tw) / cw;
|
374
495
|
spr.ty3 = (cy + th) / ch;
|
375
|
-
|
496
|
+
|
376
497
|
spr.tx4 = cx / cw;
|
377
498
|
spr.ty4 = (cy + th) / ch;
|
378
|
-
|
379
|
-
// Store the sprite
|
380
|
-
spr.width = w;
|
381
|
-
spr.height = h;
|
499
|
+
|
500
|
+
// Store the sprite dimensions
|
501
|
+
spr.width = (spr.width / spr.clip_width ) * w;
|
502
|
+
spr.height = (spr.height / spr.clip_height) * h;
|
503
|
+
spr.clip_width = w;
|
504
|
+
spr.clip_height = h;
|
382
505
|
};
|
383
506
|
|
384
507
|
|
@@ -397,37 +520,39 @@ S2D.DrawSprite = function(spr) {
|
|
397
520
|
* Create text, given a font file path, the message, and size
|
398
521
|
*/
|
399
522
|
S2D.CreateText = function(font, msg, size) {
|
400
|
-
|
523
|
+
|
401
524
|
// Create image object
|
402
525
|
var txt = Object.create(S2D.Text);
|
403
526
|
txt.color = Object.create(S2D.Color);
|
404
|
-
txt.font = font;
|
527
|
+
txt.font = font ? font : null;
|
405
528
|
txt.msg = msg;
|
406
529
|
txt.size = size;
|
407
|
-
|
530
|
+
|
531
|
+
S2D.SetText(txt, txt.msg);
|
532
|
+
|
408
533
|
return txt;
|
409
534
|
};
|
410
535
|
|
411
536
|
|
412
537
|
/*
|
413
|
-
* Sets the text message
|
414
|
-
*/
|
538
|
+
* Sets the text message
|
539
|
+
*/
|
415
540
|
S2D.SetText = function(txt, msg) {
|
416
541
|
if (msg == "") return; // no need to create a texture
|
417
|
-
|
418
|
-
S2D.GL.FreeTexture(txt.texture);
|
419
|
-
|
542
|
+
|
543
|
+
if (txt.texture) S2D.GL.FreeTexture(txt.texture);
|
544
|
+
|
420
545
|
// Create a canvas element to make a texture
|
421
546
|
var ctx = document.createElement("canvas").getContext("2d");
|
422
|
-
|
547
|
+
|
423
548
|
// TODO: Width and height should probably be variable, based on
|
424
549
|
// `ctx.measureText(msg).width` or something.
|
425
550
|
var w = 1000;
|
426
551
|
var h = 1000;
|
427
|
-
|
552
|
+
|
428
553
|
// Double size of font for high DPI
|
429
554
|
var size = txt.size * 2;
|
430
|
-
|
555
|
+
|
431
556
|
// Set context attributes and draw text
|
432
557
|
ctx.canvas.width = w;
|
433
558
|
ctx.canvas.height = h;
|
@@ -436,7 +561,7 @@ S2D.SetText = function(txt, msg) {
|
|
436
561
|
ctx.textBaseline = "bottom";
|
437
562
|
ctx.fillStyle = "white";
|
438
563
|
ctx.fillText(msg, w, h);
|
439
|
-
|
564
|
+
|
440
565
|
txt.data = S2D.TrimCanvas(ctx.canvas); // trim the transparent pixels
|
441
566
|
txt.texture = S2D.GL.CreateTexture(txt.data);
|
442
567
|
txt.width = txt.data.width / 2; // half size of texture for high DPI
|
@@ -449,11 +574,7 @@ S2D.SetText = function(txt, msg) {
|
|
449
574
|
*/
|
450
575
|
S2D.DrawText = function(txt) {
|
451
576
|
if (!txt) return;
|
452
|
-
|
453
|
-
if (!txt.texture) {
|
454
|
-
S2D.SetText(txt, txt.msg);
|
455
|
-
}
|
456
|
-
|
577
|
+
if (!txt.texture) S2D.SetText(txt, txt.msg);
|
457
578
|
S2D.GL.DrawText(txt);
|
458
579
|
};
|
459
580
|
|
@@ -464,12 +585,12 @@ S2D.DrawText = function(txt) {
|
|
464
585
|
* Create a sound, given an audio file path
|
465
586
|
*/
|
466
587
|
S2D.CreateSound = function(path) {
|
467
|
-
|
588
|
+
|
468
589
|
// TODO: Check if audio file exists
|
469
|
-
|
590
|
+
|
470
591
|
var sound = Object.create(S2D.Sound);
|
471
592
|
sound.data = new Audio(path);
|
472
|
-
|
593
|
+
|
473
594
|
return sound;
|
474
595
|
};
|
475
596
|
|
@@ -489,12 +610,12 @@ S2D.PlaySound = function(sound) {
|
|
489
610
|
* Create the music, given an audio file path
|
490
611
|
*/
|
491
612
|
S2D.CreateMusic = function(path) {
|
492
|
-
|
613
|
+
|
493
614
|
// TODO: Check if audio file exists
|
494
|
-
|
615
|
+
|
495
616
|
var music = Object.create(S2D.Music);
|
496
617
|
music.data = new Audio(path);
|
497
|
-
|
618
|
+
|
498
619
|
return music;
|
499
620
|
};
|
500
621
|
|
@@ -543,12 +664,12 @@ S2D.StopMusic = function() {
|
|
543
664
|
*/
|
544
665
|
S2D.FadeOutMusic = function(ms) {
|
545
666
|
if (!S2D.current_music) return;
|
546
|
-
|
667
|
+
|
547
668
|
if (S2D.current_music.paused) {
|
548
669
|
S2D.StopMusic();
|
549
670
|
return;
|
550
671
|
}
|
551
|
-
|
672
|
+
|
552
673
|
var fadeAudio = setInterval(function () {
|
553
674
|
if (S2D.current_music.volume >= 0.05) {
|
554
675
|
S2D.current_music.volume -= 0.05;
|
@@ -557,7 +678,7 @@ S2D.FadeOutMusic = function(ms) {
|
|
557
678
|
S2D.current_music.volume = 1.0;
|
558
679
|
clearInterval(fadeAudio);
|
559
680
|
}
|
560
|
-
|
681
|
+
|
561
682
|
}, ms / 20);
|
562
683
|
};
|
563
684
|
|
@@ -568,30 +689,30 @@ S2D.FadeOutMusic = function(ms) {
|
|
568
689
|
* Get the mouse coordinates relative to the viewport
|
569
690
|
*/
|
570
691
|
S2D.GetMouseOnViewport = function(win, wx, wy) {
|
571
|
-
|
692
|
+
|
572
693
|
var scale; // viewport scale factor
|
573
694
|
var w, h; // width and height of scaled viewport
|
574
695
|
var x, y; // mouse positions to be returned
|
575
|
-
|
696
|
+
|
576
697
|
switch (win.viewport.mode) {
|
577
|
-
|
698
|
+
|
578
699
|
case S2D.FIXED:
|
579
700
|
x = wx / (win.orig_width / win.viewport.width);
|
580
701
|
y = wy / (win.orig_height / win.viewport.height);
|
581
702
|
break;
|
582
|
-
|
703
|
+
|
583
704
|
case S2D.SCALE:
|
584
705
|
var o = S2D.GL.GetViewportScale(win);
|
585
706
|
x = wx * 1 / o.scale - (win.width - o.w) / (2.0 * o.scale);
|
586
707
|
y = wy * 1 / o.scale - (win.height - o.h) / (2.0 * o.scale);
|
587
708
|
break;
|
588
|
-
|
709
|
+
|
589
710
|
case S2D.STRETCH:
|
590
711
|
x = wx * win.viewport.width / win.width;
|
591
712
|
y = wy * win.viewport.height / win.height;
|
592
713
|
break;
|
593
714
|
}
|
594
|
-
|
715
|
+
|
595
716
|
return {
|
596
717
|
x: x,
|
597
718
|
y: y
|
@@ -599,15 +720,34 @@ S2D.GetMouseOnViewport = function(win, wx, wy) {
|
|
599
720
|
};
|
600
721
|
|
601
722
|
|
723
|
+
/*
|
724
|
+
* Get the mouse button name from its code
|
725
|
+
*/
|
726
|
+
S2D.GetMouseButtonName = function(code) {
|
727
|
+
switch (code) {
|
728
|
+
case 0:
|
729
|
+
return S2D.MOUSE_LEFT;
|
730
|
+
case 1:
|
731
|
+
return S2D.MOUSE_MIDDLE;
|
732
|
+
case 2:
|
733
|
+
return S2D.MOUSE_RIGHT;
|
734
|
+
case 3:
|
735
|
+
return S2D.MOUSE_X1;
|
736
|
+
case 4:
|
737
|
+
return S2D.MOUSE_X2;
|
738
|
+
}
|
739
|
+
};
|
740
|
+
|
741
|
+
|
602
742
|
// window.js
|
603
743
|
|
604
744
|
/*
|
605
745
|
* Create a window
|
606
746
|
*/
|
607
747
|
S2D.CreateWindow = function(title, width, height, update, render, element, opts) {
|
608
|
-
|
748
|
+
|
609
749
|
var win = Object.create(S2D.Window);
|
610
|
-
|
750
|
+
|
611
751
|
win.title = title;
|
612
752
|
win.width = width;
|
613
753
|
win.height = height;
|
@@ -623,14 +763,14 @@ S2D.CreateWindow = function(title, width, height, update, render, element, opts)
|
|
623
763
|
win.background.g = 0;
|
624
764
|
win.background.b = 0;
|
625
765
|
win.background.a = 1;
|
626
|
-
|
766
|
+
|
627
767
|
// `element` can be an ID string (e.g. "#game") or an actual DOM element
|
628
768
|
if (typeof(element) == 'string') {
|
629
769
|
win.element = document.getElementById(element);
|
630
770
|
} else {
|
631
771
|
win.element = element;
|
632
772
|
}
|
633
|
-
|
773
|
+
|
634
774
|
return win;
|
635
775
|
};
|
636
776
|
|
@@ -639,53 +779,64 @@ S2D.CreateWindow = function(title, width, height, update, render, element, opts)
|
|
639
779
|
* Show the window
|
640
780
|
*/
|
641
781
|
S2D.Show = function(win) {
|
642
|
-
|
782
|
+
|
643
783
|
// Create the canvas element
|
644
|
-
|
784
|
+
|
645
785
|
var el = document.createElement('canvas');
|
646
786
|
win.element.appendChild(el);
|
647
|
-
|
787
|
+
|
648
788
|
el.setAttribute('width', win.width);
|
649
789
|
el.setAttribute('height', win.height);
|
650
790
|
el.innerHTML = "Your browser doesn't appear to support" +
|
651
791
|
"the <code><canvas></code> element.";
|
652
|
-
|
792
|
+
|
653
793
|
win.canvas = el;
|
654
|
-
|
794
|
+
|
795
|
+
// Prevent right clicking in canvas
|
796
|
+
win.canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); });
|
797
|
+
|
655
798
|
// Detect and set up canvas for high DPI
|
656
|
-
|
799
|
+
|
657
800
|
win.canvas.style.width = win.width + "px";
|
658
801
|
win.canvas.style.height = win.height + "px";
|
659
|
-
|
802
|
+
|
660
803
|
var ratio = window.devicePixelRatio ||
|
661
804
|
window.webkitDevicePixelRatio ||
|
662
805
|
window.mozDevicePixelRatio ||
|
663
806
|
window.opDevicePixelRatio || 1;
|
664
|
-
|
807
|
+
|
665
808
|
win.canvas.width = win.width * devicePixelRatio;
|
666
809
|
win.canvas.height = win.height * devicePixelRatio;
|
667
810
|
win.pixel_ratio = ratio;
|
668
|
-
|
811
|
+
|
669
812
|
// Initialize WebGL
|
670
813
|
S2D.GL.Init(win);
|
671
|
-
|
814
|
+
|
672
815
|
S2D.onkeydown = function(e) {
|
673
|
-
|
674
|
-
|
675
|
-
S2D.keys_down.
|
676
|
-
|
816
|
+
if (win.on_key) {
|
817
|
+
var key = S2D.GetKey(e.keyCode);
|
818
|
+
if (!S2D.keys_down.includes(key)) {
|
819
|
+
S2D.keys_down.push(key);
|
820
|
+
var event = Object.create(S2D.Event);
|
821
|
+
event.type = S2D.KEY_DOWN; event.key = key;
|
822
|
+
win.on_key(event);
|
823
|
+
}
|
677
824
|
}
|
678
825
|
};
|
679
826
|
document.addEventListener("keydown", S2D.onkeydown);
|
680
|
-
|
827
|
+
|
681
828
|
S2D.onkeyup = function(e) {
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
829
|
+
if (win.on_key) {
|
830
|
+
var key = S2D.GetKey(e.keyCode);
|
831
|
+
var i = S2D.keys_down.indexOf(key);
|
832
|
+
if (i > -1) S2D.keys_down.splice(i, 1);
|
833
|
+
var event = Object.create(S2D.Event);
|
834
|
+
event.type = S2D.KEY_UP; event.key = key;
|
835
|
+
win.on_key(event);
|
836
|
+
}
|
686
837
|
};
|
687
838
|
document.addEventListener("keyup", S2D.onkeyup);
|
688
|
-
|
839
|
+
|
689
840
|
// Clear keys down list when focus is lost
|
690
841
|
window.addEventListener("blur", function functionName() {
|
691
842
|
var e = {};
|
@@ -694,60 +845,107 @@ S2D.Show = function(win) {
|
|
694
845
|
S2D.onkeyup(e);
|
695
846
|
});
|
696
847
|
});
|
697
|
-
|
848
|
+
|
698
849
|
S2D.onmousedown = function(e) {
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
850
|
+
if (win.on_mouse) {
|
851
|
+
var o = S2D.GetMouseOnViewport(win,
|
852
|
+
e.pageX - win.canvas.offsetLeft, e.pageY - win.canvas.offsetTop
|
853
|
+
);
|
854
|
+
var event = Object.create(S2D.Event);
|
855
|
+
event.type = S2D.MOUSE_DOWN;
|
856
|
+
event.button = S2D.GetMouseButtonName(e.button);
|
857
|
+
event.x = o.x; event.y = o.y;
|
858
|
+
win.on_mouse(event);
|
859
|
+
}
|
703
860
|
};
|
704
861
|
document.addEventListener("mousedown", S2D.onmousedown);
|
705
|
-
|
706
|
-
|
862
|
+
|
863
|
+
S2D.onmouseup = function(e) {
|
864
|
+
if (win.on_mouse) {
|
865
|
+
var o = S2D.GetMouseOnViewport(win,
|
866
|
+
e.pageX - win.canvas.offsetLeft, e.pageY - win.canvas.offsetTop
|
867
|
+
);
|
868
|
+
var event = Object.create(S2D.Event);
|
869
|
+
event.type = S2D.MOUSE_UP;
|
870
|
+
event.button = S2D.GetMouseButtonName(e.button);
|
871
|
+
event.x = o.x; event.y = o.y;
|
872
|
+
win.on_mouse(event);
|
873
|
+
}
|
874
|
+
};
|
875
|
+
document.addEventListener("mouseup", S2D.onmouseup);
|
876
|
+
|
877
|
+
// Get and store mouse position, call mouse move
|
707
878
|
S2D.onmousemove = function(e) {
|
708
|
-
var
|
709
|
-
|
710
|
-
|
879
|
+
var o = S2D.GetMouseOnViewport(win,
|
880
|
+
e.pageX - win.canvas.offsetLeft, e.pageY - win.canvas.offsetTop
|
881
|
+
);
|
711
882
|
win.mouse.x = o.x;
|
712
883
|
win.mouse.y = o.y;
|
884
|
+
if (win.on_mouse) {
|
885
|
+
var event = Object.create(S2D.Event);
|
886
|
+
event.type = S2D.MOUSE_MOVE;
|
887
|
+
event.x = o.x; event.y = o.y;
|
888
|
+
event.delta_x = o.x - win.mouse.last_x; event.delta_y = o.y - win.mouse.last_y;
|
889
|
+
win.on_mouse(event);
|
890
|
+
win.mouse.last_x = o.x; win.mouse.last_y = o.y;
|
891
|
+
}
|
713
892
|
};
|
714
893
|
document.addEventListener("mousemove", S2D.onmousemove);
|
715
|
-
|
894
|
+
|
895
|
+
// Get and store mouse wheel scrolling
|
896
|
+
S2D.onmousewheel = function(e) {
|
897
|
+
if (win.on_mouse) {
|
898
|
+
var event = Object.create(S2D.Event);
|
899
|
+
event.type = S2D.MOUSE_SCROLL;
|
900
|
+
event.direction = e.webkitDirectionInvertedFromDevice ?
|
901
|
+
S2D.MOUSE_SCROLL_INVERTED : S2D.MOUSE_SCROLL_NORMAL;
|
902
|
+
event.delta_x = e.deltaX;
|
903
|
+
event.delta_y = e.deltaY;
|
904
|
+
win.on_mouse(event);
|
905
|
+
}
|
906
|
+
e.preventDefault();
|
907
|
+
};
|
908
|
+
window.addWheelListener(document, S2D.onmousewheel);
|
909
|
+
|
716
910
|
// Main loop
|
717
|
-
|
911
|
+
|
718
912
|
var req; // the animation frame request
|
719
913
|
var start_ms = new Date();
|
720
914
|
var end_ms = new Date();
|
721
915
|
var elapsed_ms;
|
722
|
-
|
916
|
+
|
723
917
|
function mainLoop(win) {
|
724
|
-
|
918
|
+
|
725
919
|
if (win.close) {
|
726
920
|
cancelAnimationFrame(req);
|
727
921
|
return;
|
728
922
|
}
|
729
|
-
|
923
|
+
|
730
924
|
S2D.GL.Clear(win.background);
|
731
|
-
|
925
|
+
|
732
926
|
// Update frame counter
|
733
927
|
win.frames++;
|
734
|
-
|
928
|
+
|
735
929
|
// Calculate and store FPS
|
736
930
|
end_ms = new Date();
|
737
931
|
elapsed_ms = end_ms.getTime() - start_ms.getTime();
|
738
932
|
win.fps = win.frames / (elapsed_ms / 1000.0);
|
739
|
-
|
933
|
+
|
740
934
|
// Detect keys held down
|
741
935
|
S2D.keys_down.forEach(function(key) {
|
742
|
-
if (win.on_key)
|
936
|
+
if (win.on_key) {
|
937
|
+
var event = Object.create(S2D.Event);
|
938
|
+
event.type = S2D.KEY_HELD; event.key = key;
|
939
|
+
win.on_key(event);
|
940
|
+
}
|
743
941
|
});
|
744
|
-
|
942
|
+
|
745
943
|
if (win.update) win.update();
|
746
944
|
if (win.render) win.render();
|
747
|
-
|
945
|
+
|
748
946
|
requestAnimationFrame(function() { mainLoop(win); });
|
749
947
|
}
|
750
|
-
|
948
|
+
|
751
949
|
req = requestAnimationFrame(function() { mainLoop(win); });
|
752
950
|
};
|
753
951
|
|
@@ -789,7 +987,7 @@ var orthoMatrix = [
|
|
789
987
|
* Initialize WebGL
|
790
988
|
*/
|
791
989
|
S2D.GL.Init = function(win) {
|
792
|
-
|
990
|
+
|
793
991
|
// Initialize the GL context
|
794
992
|
try {
|
795
993
|
// Try to grab the standard context. If it fails, fallback to experimental.
|
@@ -797,13 +995,13 @@ S2D.GL.Init = function(win) {
|
|
797
995
|
} catch(e) {
|
798
996
|
console.log("GL error caught");
|
799
997
|
}
|
800
|
-
|
998
|
+
|
801
999
|
// If we don't have a GL context, give up now
|
802
1000
|
if (!gl) {
|
803
1001
|
console.error("Unable to initialize WebGL. Your browser may not support it.");
|
804
1002
|
return null;
|
805
1003
|
}
|
806
|
-
|
1004
|
+
|
807
1005
|
S2D.GL.WebGLInit();
|
808
1006
|
S2D.GL.SetViewport(win);
|
809
1007
|
};
|
@@ -813,11 +1011,11 @@ S2D.GL.Init = function(win) {
|
|
813
1011
|
* Initialize WebGL
|
814
1012
|
*/
|
815
1013
|
S2D.GL.WebGLInit = function() {
|
816
|
-
|
1014
|
+
|
817
1015
|
// Enable transparency
|
818
1016
|
gl.enable(gl.BLEND);
|
819
1017
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
820
|
-
|
1018
|
+
|
821
1019
|
// Vertex shader source string
|
822
1020
|
var vertexSource = `
|
823
1021
|
uniform mat4 u_matrix;
|
@@ -831,7 +1029,7 @@ S2D.GL.WebGLInit = function() {
|
|
831
1029
|
v_texcoord = a_texcoord;
|
832
1030
|
gl_Position = u_matrix * a_position;
|
833
1031
|
}`;
|
834
|
-
|
1032
|
+
|
835
1033
|
// Fragment shader source string
|
836
1034
|
var fragmentSource = `
|
837
1035
|
precision mediump float;
|
@@ -839,7 +1037,7 @@ S2D.GL.WebGLInit = function() {
|
|
839
1037
|
void main(void) {
|
840
1038
|
gl_FragColor = v_color;
|
841
1039
|
}`;
|
842
|
-
|
1040
|
+
|
843
1041
|
// Fragment shader source string for textures
|
844
1042
|
var texFragmentSource = `
|
845
1043
|
precision mediump float;
|
@@ -849,55 +1047,55 @@ S2D.GL.WebGLInit = function() {
|
|
849
1047
|
void main(void) {
|
850
1048
|
gl_FragColor = texture2D(s_texture, v_texcoord) * v_color;
|
851
1049
|
}`;
|
852
|
-
|
1050
|
+
|
853
1051
|
// Load the vertex and fragment shaders
|
854
1052
|
var vertexShader = S2D.GL.LoadShader( gl.VERTEX_SHADER, vertexSource, "Vertex");
|
855
1053
|
var fragmentShader = S2D.GL.LoadShader(gl.FRAGMENT_SHADER, fragmentSource, "Fragment");
|
856
1054
|
var texFragmentShader = S2D.GL.LoadShader(gl.FRAGMENT_SHADER, texFragmentSource, "Texture Fragment");
|
857
|
-
|
1055
|
+
|
858
1056
|
// Triangle Shader //
|
859
|
-
|
1057
|
+
|
860
1058
|
// Create the texture shader program object
|
861
1059
|
shaderProgram = gl.createProgram();
|
862
|
-
|
1060
|
+
|
863
1061
|
// Attach the shader objects to the program object
|
864
1062
|
gl.attachShader(shaderProgram, vertexShader);
|
865
1063
|
gl.attachShader(shaderProgram, fragmentShader);
|
866
|
-
|
1064
|
+
|
867
1065
|
// Link the shader program
|
868
1066
|
gl.linkProgram(shaderProgram);
|
869
|
-
|
1067
|
+
|
870
1068
|
// Check if linked
|
871
1069
|
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
872
1070
|
console.error("Unable to initialize the shader program.");
|
873
1071
|
}
|
874
|
-
|
1072
|
+
|
875
1073
|
// Get the attribute locations
|
876
1074
|
positionLocation = gl.getAttribLocation(shaderProgram, "a_position");
|
877
1075
|
colorLocation = gl.getAttribLocation(shaderProgram, "a_color");
|
878
|
-
|
1076
|
+
|
879
1077
|
// Texture Shader //
|
880
|
-
|
1078
|
+
|
881
1079
|
// Create the texture shader program object
|
882
1080
|
texShaderProgram = gl.createProgram();
|
883
|
-
|
1081
|
+
|
884
1082
|
// Attach the shader objects to the program object
|
885
1083
|
gl.attachShader(texShaderProgram, vertexShader);
|
886
1084
|
gl.attachShader(texShaderProgram, texFragmentShader);
|
887
|
-
|
1085
|
+
|
888
1086
|
// Link the shader program
|
889
1087
|
gl.linkProgram(texShaderProgram);
|
890
|
-
|
1088
|
+
|
891
1089
|
// Check if linked
|
892
1090
|
if (!gl.getProgramParameter(texShaderProgram, gl.LINK_STATUS)) {
|
893
1091
|
console.error("Unable to initialize the texture shader program.");
|
894
1092
|
}
|
895
|
-
|
1093
|
+
|
896
1094
|
// Get the attribute locations
|
897
1095
|
texPositionLocation = gl.getAttribLocation(texShaderProgram, "a_position");
|
898
1096
|
texColorLocation = gl.getAttribLocation(texShaderProgram, "a_color");
|
899
1097
|
texCoordLocation = gl.getAttribLocation(texShaderProgram, "a_texcoord");
|
900
|
-
|
1098
|
+
|
901
1099
|
// Get the sampler location
|
902
1100
|
samplerLocation = gl.getUniformLocation(texShaderProgram, "s_texture");
|
903
1101
|
};
|
@@ -907,17 +1105,17 @@ S2D.GL.WebGLInit = function() {
|
|
907
1105
|
* Creates a shader object, loads shader string, and compiles.
|
908
1106
|
*/
|
909
1107
|
S2D.GL.LoadShader = function(type, shaderSrc, shaderName) {
|
910
|
-
|
1108
|
+
|
911
1109
|
var shader = gl.createShader(type);
|
912
|
-
|
1110
|
+
|
913
1111
|
gl.shaderSource(shader, shaderSrc);
|
914
1112
|
gl.compileShader(shader);
|
915
|
-
|
1113
|
+
|
916
1114
|
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
917
1115
|
console.error("Error compiling shader \"" + shaderName + "\":\n" + gl.getShaderInfoLog(shader));
|
918
1116
|
return null;
|
919
1117
|
}
|
920
|
-
|
1118
|
+
|
921
1119
|
return shader;
|
922
1120
|
};
|
923
1121
|
|
@@ -926,15 +1124,15 @@ S2D.GL.LoadShader = function(type, shaderSrc, shaderName) {
|
|
926
1124
|
* Calculate the viewport's scaled width and height
|
927
1125
|
*/
|
928
1126
|
S2D.GL.GetViewportScale = function(win) {
|
929
|
-
|
1127
|
+
|
930
1128
|
var s = Math.min(
|
931
1129
|
win.width / win.viewport.width,
|
932
1130
|
win.height / win.viewport.height
|
933
1131
|
);
|
934
|
-
|
1132
|
+
|
935
1133
|
var w = win.viewport.width * s;
|
936
1134
|
var h = win.viewport.height * s;
|
937
|
-
|
1135
|
+
|
938
1136
|
return {
|
939
1137
|
w: w,
|
940
1138
|
h: h,
|
@@ -947,51 +1145,51 @@ S2D.GL.GetViewportScale = function(win) {
|
|
947
1145
|
* Sets the viewport and matrix projection
|
948
1146
|
*/
|
949
1147
|
S2D.GL.SetViewport = function(win) {
|
950
|
-
|
1148
|
+
|
951
1149
|
var ortho_w = win.viewport.width;
|
952
1150
|
var ortho_h = win.viewport.height;
|
953
1151
|
var x, y, w, h; // calculated GL viewport values
|
954
|
-
|
1152
|
+
|
955
1153
|
x = 0; y = 0; w = win.width; h = win.height;
|
956
|
-
|
1154
|
+
|
957
1155
|
switch (win.viewport.mode) {
|
958
|
-
|
1156
|
+
|
959
1157
|
case S2D.FIXED:
|
960
1158
|
w = win.orig_width;
|
961
1159
|
h = win.orig_height;
|
962
1160
|
y = win.height - h;
|
963
1161
|
break;
|
964
|
-
|
1162
|
+
|
965
1163
|
case S2D.SCALE:
|
966
1164
|
var o = S2D.GL.GetViewportScale(win);
|
967
1165
|
// Center the viewport
|
968
1166
|
x = win.width / 2.0 - o.w/2.0;
|
969
1167
|
y = win.height / 2.0 - o.h/2.0;
|
970
1168
|
break;
|
971
|
-
|
1169
|
+
|
972
1170
|
case S2D.STRETCH:
|
973
1171
|
break;
|
974
1172
|
}
|
975
|
-
|
1173
|
+
|
976
1174
|
gl.viewport(
|
977
1175
|
x * win.pixel_ratio,
|
978
1176
|
y * win.pixel_ratio,
|
979
1177
|
w * win.pixel_ratio,
|
980
1178
|
h * win.pixel_ratio
|
981
1179
|
);
|
982
|
-
|
1180
|
+
|
983
1181
|
orthoMatrix[0] = 2.0 / ortho_w;
|
984
1182
|
orthoMatrix[5] = -2.0 / ortho_h;
|
985
|
-
|
1183
|
+
|
986
1184
|
gl.useProgram(shaderProgram);
|
987
|
-
|
1185
|
+
|
988
1186
|
gl.uniformMatrix4fv(
|
989
1187
|
gl.getUniformLocation(shaderProgram, "u_matrix"),
|
990
1188
|
false, new Float32Array(orthoMatrix)
|
991
1189
|
);
|
992
|
-
|
1190
|
+
|
993
1191
|
gl.useProgram(texShaderProgram);
|
994
|
-
|
1192
|
+
|
995
1193
|
gl.uniformMatrix4fv(
|
996
1194
|
gl.getUniformLocation(texShaderProgram, "u_matrix"),
|
997
1195
|
false, new Float32Array(orthoMatrix)
|
@@ -1012,24 +1210,25 @@ S2D.GL.Clear = function(clr) {
|
|
1012
1210
|
* Creates a texture for rendering
|
1013
1211
|
*/
|
1014
1212
|
S2D.GL.CreateTexture = function(data) {
|
1015
|
-
|
1213
|
+
if (!gl) return;
|
1214
|
+
|
1016
1215
|
var texture = gl.createTexture();
|
1017
|
-
|
1216
|
+
|
1018
1217
|
// Bind the named texture to a texturing target
|
1019
1218
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
1020
|
-
|
1219
|
+
|
1021
1220
|
// Specifies the 2D texture image
|
1022
1221
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
1023
|
-
|
1222
|
+
|
1024
1223
|
// Set the filtering mode
|
1025
1224
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
1026
1225
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
1027
|
-
|
1226
|
+
|
1028
1227
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
1029
1228
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
1030
|
-
|
1229
|
+
|
1031
1230
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
1032
|
-
|
1231
|
+
|
1033
1232
|
return texture;
|
1034
1233
|
};
|
1035
1234
|
|
@@ -1045,38 +1244,38 @@ S2D.GL.FreeTexture = function(texture) {
|
|
1045
1244
|
/*
|
1046
1245
|
* Draw triangle
|
1047
1246
|
*/
|
1048
|
-
S2D.GL.DrawTriangle = function(x1, y1,
|
1049
|
-
x2, y2,
|
1050
|
-
x3, y3,
|
1051
|
-
|
1247
|
+
S2D.GL.DrawTriangle = function(x1, y1, r1, g1, b1, a1,
|
1248
|
+
x2, y2, r2, g2, b2, a2,
|
1249
|
+
x3, y3, r3, g3, b3, a3) {
|
1250
|
+
|
1052
1251
|
var vertices = [
|
1053
1252
|
x1, y1, 0.0,
|
1054
1253
|
x2, y2, 0.0,
|
1055
1254
|
x3, y3, 0.0
|
1056
1255
|
];
|
1057
|
-
|
1256
|
+
|
1058
1257
|
var colors = [
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1258
|
+
r1, g1, b1, a1,
|
1259
|
+
r2, g2, b2, a2,
|
1260
|
+
r3, g3, b3, a3
|
1062
1261
|
];
|
1063
|
-
|
1262
|
+
|
1064
1263
|
gl.useProgram(shaderProgram);
|
1065
|
-
|
1264
|
+
|
1066
1265
|
// Vertex
|
1067
1266
|
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
|
1068
1267
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
|
1069
|
-
|
1268
|
+
|
1070
1269
|
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
|
1071
1270
|
gl.enableVertexAttribArray(positionLocation);
|
1072
|
-
|
1271
|
+
|
1073
1272
|
// Colors
|
1074
1273
|
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
|
1075
1274
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
|
1076
|
-
|
1275
|
+
|
1077
1276
|
gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
|
1078
1277
|
gl.enableVertexAttribArray(colorLocation);
|
1079
|
-
|
1278
|
+
|
1080
1279
|
// Draw
|
1081
1280
|
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
1082
1281
|
};
|
@@ -1089,48 +1288,48 @@ S2D.GL.DrawTexture = function(x, y, w, h,
|
|
1089
1288
|
r, g, b, a,
|
1090
1289
|
tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4,
|
1091
1290
|
texture) {
|
1092
|
-
|
1291
|
+
|
1093
1292
|
var vertices =
|
1094
1293
|
// x, y coords | x, y texture coords
|
1095
1294
|
[ x, y, 0.0, tx1, ty1,
|
1096
1295
|
x + w, y, 0.0, tx2, ty2,
|
1097
1296
|
x + w, y + h, 0.0, tx3, ty3,
|
1098
1297
|
x, y + h, 0.0, tx4, ty4 ];
|
1099
|
-
|
1298
|
+
|
1100
1299
|
var colors = [
|
1101
1300
|
r, g, b, a,
|
1102
1301
|
r, g, b, a,
|
1103
1302
|
r, g, b, a,
|
1104
1303
|
r, g, b, a
|
1105
1304
|
];
|
1106
|
-
|
1305
|
+
|
1107
1306
|
gl.useProgram(texShaderProgram);
|
1108
|
-
|
1307
|
+
|
1109
1308
|
// Vertex
|
1110
1309
|
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
|
1111
1310
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
|
1112
|
-
|
1311
|
+
|
1113
1312
|
gl.vertexAttribPointer(texPositionLocation, 3, gl.FLOAT, false, 5*4, 0);
|
1114
1313
|
gl.enableVertexAttribArray(texPositionLocation);
|
1115
|
-
|
1314
|
+
|
1116
1315
|
gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 5*4, 3*4);
|
1117
1316
|
gl.enableVertexAttribArray(texCoordLocation);
|
1118
|
-
|
1317
|
+
|
1119
1318
|
// Colors
|
1120
1319
|
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
|
1121
1320
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
|
1122
|
-
|
1321
|
+
|
1123
1322
|
gl.vertexAttribPointer(texColorLocation, 4, gl.FLOAT, false, 0, 0);
|
1124
1323
|
gl.enableVertexAttribArray(texColorLocation);
|
1125
|
-
|
1324
|
+
|
1126
1325
|
gl.activeTexture(gl.TEXTURE0);
|
1127
1326
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
1128
|
-
|
1327
|
+
|
1129
1328
|
gl.uniform1i(samplerLocation, 0);
|
1130
|
-
|
1329
|
+
|
1131
1330
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
|
1132
1331
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
|
1133
|
-
|
1332
|
+
|
1134
1333
|
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
|
1135
1334
|
};
|
1136
1335
|
|
@@ -1154,7 +1353,7 @@ S2D.GL.DrawImage = function(img) {
|
|
1154
1353
|
S2D.GL.DrawSprite = function(spr) {
|
1155
1354
|
S2D.GL.DrawTexture(
|
1156
1355
|
spr.x, spr.y, spr.width, spr.height,
|
1157
|
-
spr.
|
1356
|
+
spr.color.r, spr.color.g, spr.color.b, spr.color.a,
|
1158
1357
|
spr.tx1, spr.ty1, spr.tx2, spr.ty2, spr.tx3, spr.ty3, spr.tx4, spr.ty4,
|
1159
1358
|
spr.img.texture
|
1160
1359
|
);
|