bloody-engine 1.0.3 → 1.0.5
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.
- package/dist/node/index.js +400 -0
- package/dist/web/core/buffer.d.ts +58 -0
- package/dist/web/core/buffer.d.ts.map +1 -0
- package/dist/web/core/grahpic-device.d.ts +66 -0
- package/dist/web/core/grahpic-device.d.ts.map +1 -0
- package/dist/web/core/index.d.ts +8 -0
- package/dist/web/core/index.d.ts.map +1 -0
- package/dist/web/core/resource-loader-factory.d.ts +90 -0
- package/dist/web/core/resource-loader-factory.d.ts.map +1 -0
- package/dist/web/core/resource-loader.d.ts +71 -0
- package/dist/web/core/resource-loader.d.ts.map +1 -0
- package/dist/web/core/resource-pipeline.d.ts +139 -0
- package/dist/web/core/resource-pipeline.d.ts.map +1 -0
- package/dist/web/core/shader.d.ts +62 -0
- package/dist/web/core/shader.d.ts.map +1 -0
- package/dist/web/core/texture.d.ts +69 -0
- package/dist/web/core/texture.d.ts.map +1 -0
- package/dist/web/demo-node.d.ts +2 -0
- package/dist/web/demo-node.d.ts.map +1 -0
- package/dist/web/examples/batch-renderer-demo.d.ts +10 -0
- package/dist/web/examples/batch-renderer-demo.d.ts.map +1 -0
- package/dist/web/examples/projection-examples.d.ts +87 -0
- package/dist/web/examples/projection-examples.d.ts.map +1 -0
- package/dist/web/examples/resource-loader-demo.d.ts +14 -0
- package/dist/web/examples/resource-loader-demo.d.ts.map +1 -0
- package/dist/web/examples/shader-examples.d.ts +92 -0
- package/dist/web/examples/shader-examples.d.ts.map +1 -0
- package/dist/web/examples/sprite-batch-renderer-demo.d.ts +12 -0
- package/dist/web/examples/sprite-batch-renderer-demo.d.ts.map +1 -0
- package/dist/web/index.d.ts +7 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +760 -474
- package/dist/web/index.umd.js +23 -23
- package/dist/web/platforms/browser/browser-context.d.ts +31 -0
- package/dist/web/platforms/browser/browser-context.d.ts.map +1 -0
- package/dist/web/platforms/browser/browser-resource-loader.d.ts +67 -0
- package/dist/web/platforms/browser/browser-resource-loader.d.ts.map +1 -0
- package/dist/web/platforms/node/node-context.d.ts +31 -0
- package/dist/web/platforms/node/node-context.d.ts.map +1 -0
- package/dist/web/platforms/node/node-resource-loader.d.ts +73 -0
- package/dist/web/platforms/node/node-resource-loader.d.ts.map +1 -0
- package/dist/web/platforms/node/sdl-window.d.ts +41 -0
- package/dist/web/platforms/node/sdl-window.d.ts.map +1 -0
- package/dist/web/projection.test.d.ts +5 -0
- package/dist/web/projection.test.d.ts.map +1 -0
- package/dist/web/public-api.d.ts +25 -0
- package/dist/web/public-api.d.ts.map +1 -0
- package/dist/web/rendering/batch-renderer.d.ts +273 -0
- package/dist/web/rendering/batch-renderer.d.ts.map +1 -0
- package/dist/web/rendering/camera.d.ts +153 -0
- package/dist/web/rendering/camera.d.ts.map +1 -0
- package/dist/web/rendering/projection.d.ts +108 -0
- package/dist/web/rendering/projection.d.ts.map +1 -0
- package/dist/web/rendering/rendering-context-factory.d.ts +24 -0
- package/dist/web/rendering/rendering-context-factory.d.ts.map +1 -0
- package/dist/web/rendering/rendering-context.d.ts +77 -0
- package/dist/web/rendering/rendering-context.d.ts.map +1 -0
- package/dist/web/rendering/vertex.d.ts +98 -0
- package/dist/web/rendering/vertex.d.ts.map +1 -0
- package/dist/web/scene/scene.d.ts +139 -0
- package/dist/web/scene/scene.d.ts.map +1 -0
- package/package.json +5 -4
package/dist/node/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import createGL from "gl";
|
|
2
|
+
import sdl from "@kmamal/sdl";
|
|
2
3
|
import * as fs from "fs/promises";
|
|
3
4
|
import * as path from "path";
|
|
4
5
|
class BrowserRenderingContext {
|
|
@@ -365,6 +366,99 @@ class GraphicsDevice {
|
|
|
365
366
|
);
|
|
366
367
|
}
|
|
367
368
|
}
|
|
369
|
+
class SDLWindow {
|
|
370
|
+
constructor(width, height, title = "Bloody Engine") {
|
|
371
|
+
this.closed = false;
|
|
372
|
+
this.width = width;
|
|
373
|
+
this.height = height;
|
|
374
|
+
this.title = title;
|
|
375
|
+
try {
|
|
376
|
+
this.window = sdl.video.createWindow({
|
|
377
|
+
width: this.width,
|
|
378
|
+
height: this.height,
|
|
379
|
+
title: this.title
|
|
380
|
+
});
|
|
381
|
+
if (!this.window) {
|
|
382
|
+
throw new Error("Failed to create SDL window");
|
|
383
|
+
}
|
|
384
|
+
this.window.on("close", () => {
|
|
385
|
+
this.closed = true;
|
|
386
|
+
});
|
|
387
|
+
console.log(`✓ SDL Window created (${width}x${height}): "${title}"`);
|
|
388
|
+
} catch (error) {
|
|
389
|
+
this.cleanup();
|
|
390
|
+
throw new Error(`Window creation failed: ${error}`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Get window dimensions
|
|
395
|
+
*/
|
|
396
|
+
getDimensions() {
|
|
397
|
+
return { width: this.width, height: this.height };
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Display pixel data in the window
|
|
401
|
+
* @param pixels Uint8Array of RGBA pixel data
|
|
402
|
+
*/
|
|
403
|
+
updatePixels(pixels) {
|
|
404
|
+
if (!this.window || this.closed) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const buffer2 = Buffer.from(pixels);
|
|
409
|
+
const stride = this.width * 4;
|
|
410
|
+
this.window.render(this.width, this.height, stride, "rgba32", buffer2);
|
|
411
|
+
} catch (error) {
|
|
412
|
+
console.error("Failed to update pixels:", error);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Register an event handler
|
|
417
|
+
*/
|
|
418
|
+
on(eventName, handler) {
|
|
419
|
+
if (!this.window || this.closed) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
this.window.on(eventName, (event) => {
|
|
424
|
+
try {
|
|
425
|
+
handler(event);
|
|
426
|
+
} catch (error) {
|
|
427
|
+
console.error(`Error in ${eventName} handler:`, error);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
} catch (error) {
|
|
431
|
+
console.error(`Error registering ${eventName} handler:`, error);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Check if window is still open
|
|
436
|
+
*/
|
|
437
|
+
isOpen() {
|
|
438
|
+
return this.window !== null && !this.closed;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Cleanup and close window
|
|
442
|
+
*/
|
|
443
|
+
cleanup() {
|
|
444
|
+
if (this.window && !this.closed) {
|
|
445
|
+
try {
|
|
446
|
+
this.window.destroy();
|
|
447
|
+
} catch (error) {
|
|
448
|
+
console.warn("Error destroying window:", error);
|
|
449
|
+
}
|
|
450
|
+
this.window = null;
|
|
451
|
+
this.closed = true;
|
|
452
|
+
}
|
|
453
|
+
console.log("✓ SDL Window cleaned up");
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Destroy the window (alias for cleanup)
|
|
457
|
+
*/
|
|
458
|
+
destroy() {
|
|
459
|
+
this.cleanup();
|
|
460
|
+
}
|
|
461
|
+
}
|
|
368
462
|
class Texture {
|
|
369
463
|
/**
|
|
370
464
|
* Create a texture from pixel data
|
|
@@ -1132,6 +1226,301 @@ class SpriteBatchRenderer {
|
|
|
1132
1226
|
}
|
|
1133
1227
|
}
|
|
1134
1228
|
}
|
|
1229
|
+
class GPUBasedSpriteBatchRenderer {
|
|
1230
|
+
/**
|
|
1231
|
+
* Create a new GPU-based sprite batch renderer (V3)
|
|
1232
|
+
* @param gl WebGL rendering context
|
|
1233
|
+
* @param shader Shader program to use (should be SHADERS_V3)
|
|
1234
|
+
* @param maxQuads Maximum number of quads to batch (default 1000)
|
|
1235
|
+
* @param tileSize Tile size for isometric projection (default {width: 64, height: 32})
|
|
1236
|
+
* @param zScale Scale factor for Z height (default 1.0)
|
|
1237
|
+
*/
|
|
1238
|
+
constructor(gl, shader, maxQuads = 1e3, tileSize = { width: 64, height: 32 }, zScale = 1) {
|
|
1239
|
+
this.vertexBuffer = null;
|
|
1240
|
+
this.quads = [];
|
|
1241
|
+
this.isDirty = false;
|
|
1242
|
+
this.verticesPerQuad = 6;
|
|
1243
|
+
this.floatsPerVertex = 12;
|
|
1244
|
+
this.texture = null;
|
|
1245
|
+
this.depthTestEnabled = true;
|
|
1246
|
+
this.gl = gl;
|
|
1247
|
+
this.shader = shader;
|
|
1248
|
+
this.maxQuads = maxQuads;
|
|
1249
|
+
this.tileSize = tileSize;
|
|
1250
|
+
this.zScale = zScale;
|
|
1251
|
+
this.resolution = { width: gl.canvas.width, height: gl.canvas.height };
|
|
1252
|
+
const totalFloats = maxQuads * this.verticesPerQuad * this.floatsPerVertex;
|
|
1253
|
+
this.vertexData = new Float32Array(totalFloats);
|
|
1254
|
+
const buf = gl.createBuffer();
|
|
1255
|
+
if (!buf) {
|
|
1256
|
+
throw new Error("Failed to create vertex buffer");
|
|
1257
|
+
}
|
|
1258
|
+
this.vertexBuffer = buf;
|
|
1259
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
1260
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData.byteLength, gl.DYNAMIC_DRAW);
|
|
1261
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Set the texture for batch rendering
|
|
1265
|
+
* @param texture The texture to use when rendering
|
|
1266
|
+
*/
|
|
1267
|
+
setTexture(texture) {
|
|
1268
|
+
this.texture = texture;
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Add a sprite quad to the batch
|
|
1272
|
+
* If gridX and gridY are provided, uses GPU transformation.
|
|
1273
|
+
* Otherwise, converts x, y to grid coordinates.
|
|
1274
|
+
* @param quad Sprite quad instance to add
|
|
1275
|
+
*/
|
|
1276
|
+
addQuad(quad) {
|
|
1277
|
+
if (this.quads.length >= this.maxQuads) {
|
|
1278
|
+
console.warn(`Sprite batch renderer at max capacity (${this.maxQuads})`);
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
this.quads.push(quad);
|
|
1282
|
+
this.isDirty = true;
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Clear all quads from the batch
|
|
1286
|
+
*/
|
|
1287
|
+
clear() {
|
|
1288
|
+
this.quads = [];
|
|
1289
|
+
this.isDirty = true;
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Get number of quads currently in batch
|
|
1293
|
+
*/
|
|
1294
|
+
getQuadCount() {
|
|
1295
|
+
return this.quads.length;
|
|
1296
|
+
}
|
|
1297
|
+
/**
|
|
1298
|
+
* Update the batch - rebuilds vertex buffer if quads changed
|
|
1299
|
+
*/
|
|
1300
|
+
update() {
|
|
1301
|
+
if (!this.isDirty || this.quads.length === 0) {
|
|
1302
|
+
return;
|
|
1303
|
+
}
|
|
1304
|
+
let vertexIndex = 0;
|
|
1305
|
+
for (const quad of this.quads) {
|
|
1306
|
+
const {
|
|
1307
|
+
x,
|
|
1308
|
+
y,
|
|
1309
|
+
z = 0,
|
|
1310
|
+
width,
|
|
1311
|
+
height,
|
|
1312
|
+
color = { r: 1, g: 1, b: 1, a: 1 },
|
|
1313
|
+
uvRect = { uMin: 0, vMin: 0, uMax: 1, vMax: 1 },
|
|
1314
|
+
texIndex = 0,
|
|
1315
|
+
gridX,
|
|
1316
|
+
gridY
|
|
1317
|
+
} = quad;
|
|
1318
|
+
let gx, gy;
|
|
1319
|
+
if (gridX !== void 0 && gridY !== void 0) {
|
|
1320
|
+
gx = gridX;
|
|
1321
|
+
gy = gridY;
|
|
1322
|
+
} else {
|
|
1323
|
+
gx = (x / (this.tileSize.width * 0.5) + y / (this.tileSize.height * 0.5)) * 0.5;
|
|
1324
|
+
gy = (y / (this.tileSize.height * 0.5) - x / (this.tileSize.width * 0.5)) * 0.5;
|
|
1325
|
+
}
|
|
1326
|
+
const halfW = width / 2;
|
|
1327
|
+
const halfH = height / 2;
|
|
1328
|
+
const corners = [
|
|
1329
|
+
[-halfW, -halfH],
|
|
1330
|
+
// bottom-left
|
|
1331
|
+
[halfW, -halfH],
|
|
1332
|
+
// bottom-right
|
|
1333
|
+
[halfW, halfH],
|
|
1334
|
+
// top-right
|
|
1335
|
+
[halfW, halfH],
|
|
1336
|
+
// top-right (duplicate)
|
|
1337
|
+
[-halfH, halfH],
|
|
1338
|
+
// top-left
|
|
1339
|
+
[-halfW, -halfH]
|
|
1340
|
+
// bottom-left (duplicate)
|
|
1341
|
+
];
|
|
1342
|
+
const texCoords = [
|
|
1343
|
+
[uvRect.uMin, uvRect.vMin],
|
|
1344
|
+
[uvRect.uMax, uvRect.vMin],
|
|
1345
|
+
[uvRect.uMax, uvRect.vMax],
|
|
1346
|
+
[uvRect.uMax, uvRect.vMax],
|
|
1347
|
+
[uvRect.uMin, uvRect.vMax],
|
|
1348
|
+
[uvRect.uMin, uvRect.vMin]
|
|
1349
|
+
];
|
|
1350
|
+
for (let i = 0; i < corners.length; i++) {
|
|
1351
|
+
const [localX, localY] = corners[i];
|
|
1352
|
+
const [u, v] = texCoords[i];
|
|
1353
|
+
this.vertexData[vertexIndex++] = gx;
|
|
1354
|
+
this.vertexData[vertexIndex++] = gy;
|
|
1355
|
+
this.vertexData[vertexIndex++] = z;
|
|
1356
|
+
this.vertexData[vertexIndex++] = localX;
|
|
1357
|
+
this.vertexData[vertexIndex++] = localY;
|
|
1358
|
+
this.vertexData[vertexIndex++] = u;
|
|
1359
|
+
this.vertexData[vertexIndex++] = v;
|
|
1360
|
+
this.vertexData[vertexIndex++] = color.r;
|
|
1361
|
+
this.vertexData[vertexIndex++] = color.g;
|
|
1362
|
+
this.vertexData[vertexIndex++] = color.b;
|
|
1363
|
+
this.vertexData[vertexIndex++] = color.a;
|
|
1364
|
+
this.vertexData[vertexIndex++] = texIndex;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
if (this.vertexBuffer) {
|
|
1368
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
1369
|
+
this.gl.bufferSubData(
|
|
1370
|
+
this.gl.ARRAY_BUFFER,
|
|
1371
|
+
0,
|
|
1372
|
+
this.vertexData.subarray(0, vertexIndex)
|
|
1373
|
+
);
|
|
1374
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
1375
|
+
}
|
|
1376
|
+
this.isDirty = false;
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Set whether depth testing is enabled
|
|
1380
|
+
* @param enabled Whether to enable depth testing (default true)
|
|
1381
|
+
*/
|
|
1382
|
+
setDepthTestEnabled(enabled) {
|
|
1383
|
+
this.depthTestEnabled = enabled;
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Render the batch with GPU-based transformation
|
|
1387
|
+
* @param camera Camera for view transform
|
|
1388
|
+
*/
|
|
1389
|
+
render(camera) {
|
|
1390
|
+
if (this.quads.length === 0) {
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
this.update();
|
|
1394
|
+
this.shader.use();
|
|
1395
|
+
if (this.depthTestEnabled) {
|
|
1396
|
+
this.gl.enable(this.gl.DEPTH_TEST);
|
|
1397
|
+
this.gl.depthFunc(this.gl.LEQUAL);
|
|
1398
|
+
} else {
|
|
1399
|
+
this.gl.disable(this.gl.DEPTH_TEST);
|
|
1400
|
+
}
|
|
1401
|
+
if (this.vertexBuffer) {
|
|
1402
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
1403
|
+
const stride = this.floatsPerVertex * 4;
|
|
1404
|
+
const attrs = {
|
|
1405
|
+
gridPosition: this.shader.getAttributeLocation("aGridPosition"),
|
|
1406
|
+
zPosition: this.shader.getAttributeLocation("aZPosition"),
|
|
1407
|
+
localOffset: this.shader.getAttributeLocation("aLocalOffset"),
|
|
1408
|
+
texCoord: this.shader.getAttributeLocation("aTexCoord"),
|
|
1409
|
+
color: this.shader.getAttributeLocation("aColor"),
|
|
1410
|
+
texIndex: this.shader.getAttributeLocation("aTexIndex")
|
|
1411
|
+
};
|
|
1412
|
+
if (attrs.gridPosition !== -1) {
|
|
1413
|
+
this.gl.enableVertexAttribArray(attrs.gridPosition);
|
|
1414
|
+
this.gl.vertexAttribPointer(
|
|
1415
|
+
attrs.gridPosition,
|
|
1416
|
+
2,
|
|
1417
|
+
this.gl.FLOAT,
|
|
1418
|
+
false,
|
|
1419
|
+
stride,
|
|
1420
|
+
0
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
if (attrs.zPosition !== -1) {
|
|
1424
|
+
this.gl.enableVertexAttribArray(attrs.zPosition);
|
|
1425
|
+
this.gl.vertexAttribPointer(
|
|
1426
|
+
attrs.zPosition,
|
|
1427
|
+
1,
|
|
1428
|
+
this.gl.FLOAT,
|
|
1429
|
+
false,
|
|
1430
|
+
stride,
|
|
1431
|
+
2 * 4
|
|
1432
|
+
);
|
|
1433
|
+
}
|
|
1434
|
+
if (attrs.localOffset !== -1) {
|
|
1435
|
+
this.gl.enableVertexAttribArray(attrs.localOffset);
|
|
1436
|
+
this.gl.vertexAttribPointer(
|
|
1437
|
+
attrs.localOffset,
|
|
1438
|
+
2,
|
|
1439
|
+
this.gl.FLOAT,
|
|
1440
|
+
false,
|
|
1441
|
+
stride,
|
|
1442
|
+
3 * 4
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
if (attrs.texCoord !== -1) {
|
|
1446
|
+
this.gl.enableVertexAttribArray(attrs.texCoord);
|
|
1447
|
+
this.gl.vertexAttribPointer(
|
|
1448
|
+
attrs.texCoord,
|
|
1449
|
+
2,
|
|
1450
|
+
this.gl.FLOAT,
|
|
1451
|
+
false,
|
|
1452
|
+
stride,
|
|
1453
|
+
5 * 4
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
if (attrs.color !== -1) {
|
|
1457
|
+
this.gl.enableVertexAttribArray(attrs.color);
|
|
1458
|
+
this.gl.vertexAttribPointer(
|
|
1459
|
+
attrs.color,
|
|
1460
|
+
4,
|
|
1461
|
+
this.gl.FLOAT,
|
|
1462
|
+
false,
|
|
1463
|
+
stride,
|
|
1464
|
+
7 * 4
|
|
1465
|
+
);
|
|
1466
|
+
}
|
|
1467
|
+
if (attrs.texIndex !== -1) {
|
|
1468
|
+
this.gl.enableVertexAttribArray(attrs.texIndex);
|
|
1469
|
+
this.gl.vertexAttribPointer(
|
|
1470
|
+
attrs.texIndex,
|
|
1471
|
+
1,
|
|
1472
|
+
this.gl.FLOAT,
|
|
1473
|
+
false,
|
|
1474
|
+
stride,
|
|
1475
|
+
11 * 4
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
if (this.texture) {
|
|
1479
|
+
this.texture.bind(0);
|
|
1480
|
+
const textureUniform = this.shader.getUniformLocation("uTexture");
|
|
1481
|
+
if (textureUniform !== null) {
|
|
1482
|
+
this.gl.uniform1i(textureUniform, 0);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
const tileSizeUniform = this.shader.getUniformLocation("uTileSize");
|
|
1486
|
+
if (tileSizeUniform !== null) {
|
|
1487
|
+
this.gl.uniform2f(tileSizeUniform, this.tileSize.width, this.tileSize.height);
|
|
1488
|
+
}
|
|
1489
|
+
const cameraUniform = this.shader.getUniformLocation("uCamera");
|
|
1490
|
+
if (cameraUniform !== null) {
|
|
1491
|
+
this.gl.uniform3f(cameraUniform, camera.x, camera.y, camera.zoom);
|
|
1492
|
+
}
|
|
1493
|
+
const zScaleUniform = this.shader.getUniformLocation("uZScale");
|
|
1494
|
+
if (zScaleUniform !== null) {
|
|
1495
|
+
this.gl.uniform1f(zScaleUniform, this.zScale);
|
|
1496
|
+
}
|
|
1497
|
+
const resolutionUniform = this.shader.getUniformLocation("uResolution");
|
|
1498
|
+
if (resolutionUniform !== null) {
|
|
1499
|
+
this.gl.uniform2f(resolutionUniform, this.resolution.width, this.resolution.height);
|
|
1500
|
+
}
|
|
1501
|
+
const rotationUniform = this.shader.getUniformLocation("uRotation");
|
|
1502
|
+
if (rotationUniform !== null) {
|
|
1503
|
+
this.gl.uniform1f(rotationUniform, 0);
|
|
1504
|
+
}
|
|
1505
|
+
const quadSizeUniform = this.shader.getUniformLocation("uQuadSize");
|
|
1506
|
+
if (quadSizeUniform !== null) {
|
|
1507
|
+
this.gl.uniform2f(quadSizeUniform, 1, 1);
|
|
1508
|
+
}
|
|
1509
|
+
const vertexCount = this.quads.length * this.verticesPerQuad;
|
|
1510
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, vertexCount);
|
|
1511
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Clean up GPU resources
|
|
1516
|
+
*/
|
|
1517
|
+
dispose() {
|
|
1518
|
+
if (this.vertexBuffer) {
|
|
1519
|
+
this.gl.deleteBuffer(this.vertexBuffer);
|
|
1520
|
+
this.vertexBuffer = null;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1135
1524
|
class Matrix4 {
|
|
1136
1525
|
/**
|
|
1137
1526
|
* Create an identity matrix
|
|
@@ -1399,6 +1788,14 @@ class Camera {
|
|
|
1399
1788
|
return { x: screenX, y: screenY };
|
|
1400
1789
|
}
|
|
1401
1790
|
}
|
|
1791
|
+
class ProjectionConfig {
|
|
1792
|
+
// Scale factor for height (vertical exaggeration)
|
|
1793
|
+
constructor(tileWidth = 64, tileHeight = 32, zScale = 1) {
|
|
1794
|
+
this.tileWidth = tileWidth;
|
|
1795
|
+
this.tileHeight = tileHeight;
|
|
1796
|
+
this.zScale = zScale;
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1402
1799
|
class BrowserResourceLoader {
|
|
1403
1800
|
/**
|
|
1404
1801
|
* Create a new browser resource loader
|
|
@@ -2341,14 +2738,17 @@ export {
|
|
|
2341
2738
|
BrowserResourceLoader,
|
|
2342
2739
|
Camera,
|
|
2343
2740
|
Environment,
|
|
2741
|
+
GPUBasedSpriteBatchRenderer,
|
|
2344
2742
|
GraphicsDevice,
|
|
2345
2743
|
IndexBuffer,
|
|
2346
2744
|
Matrix4,
|
|
2347
2745
|
NodeRenderingContext,
|
|
2348
2746
|
NodeResourceLoader,
|
|
2747
|
+
ProjectionConfig,
|
|
2349
2748
|
RenderingContextFactory,
|
|
2350
2749
|
ResourceLoaderFactory,
|
|
2351
2750
|
ResourcePipeline,
|
|
2751
|
+
SDLWindow,
|
|
2352
2752
|
Shader,
|
|
2353
2753
|
SpriteBatchRenderer,
|
|
2354
2754
|
Texture,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vertex Buffer abstraction
|
|
3
|
+
* Manages vertex data for rendering
|
|
4
|
+
*/
|
|
5
|
+
export declare class VertexBuffer {
|
|
6
|
+
private buffer;
|
|
7
|
+
private gl;
|
|
8
|
+
private vertexCount;
|
|
9
|
+
private stride;
|
|
10
|
+
constructor(gl: WebGLRenderingContext, data: Float32Array, stride?: number);
|
|
11
|
+
/**
|
|
12
|
+
* Bind buffer for rendering
|
|
13
|
+
*/
|
|
14
|
+
bind(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Unbind buffer
|
|
17
|
+
*/
|
|
18
|
+
unbind(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Get vertex count
|
|
21
|
+
*/
|
|
22
|
+
getVertexCount(): number;
|
|
23
|
+
/**
|
|
24
|
+
* Get stride
|
|
25
|
+
*/
|
|
26
|
+
getStride(): number;
|
|
27
|
+
/**
|
|
28
|
+
* Clean up resources
|
|
29
|
+
*/
|
|
30
|
+
dispose(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Index Buffer abstraction
|
|
34
|
+
* Manages index data for indexed rendering
|
|
35
|
+
*/
|
|
36
|
+
export declare class IndexBuffer {
|
|
37
|
+
private buffer;
|
|
38
|
+
private gl;
|
|
39
|
+
private indexCount;
|
|
40
|
+
constructor(gl: WebGLRenderingContext, data: Uint16Array);
|
|
41
|
+
/**
|
|
42
|
+
* Bind buffer for rendering
|
|
43
|
+
*/
|
|
44
|
+
bind(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Unbind buffer
|
|
47
|
+
*/
|
|
48
|
+
unbind(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Get index count
|
|
51
|
+
*/
|
|
52
|
+
getIndexCount(): number;
|
|
53
|
+
/**
|
|
54
|
+
* Clean up resources
|
|
55
|
+
*/
|
|
56
|
+
dispose(): void;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../../src/core/buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,EAAE,CAAwB;IAClC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAGrB,EAAE,EAAE,qBAAqB,EACzB,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,MAAU;IAoBpB;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,EAAE,CAAwB;IAClC,OAAO,CAAC,UAAU,CAAS;gBAEf,EAAE,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW;IAgBxD;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { RenderingContext } from '../rendering/rendering-context';
|
|
2
|
+
import { Shader } from './shader';
|
|
3
|
+
/**
|
|
4
|
+
* Graphics device that manages rendering context and WebGL operations
|
|
5
|
+
* Uses standardized RenderingContext interface, never directly references DOM
|
|
6
|
+
*/
|
|
7
|
+
export declare class GraphicsDevice {
|
|
8
|
+
private context;
|
|
9
|
+
constructor(width: number, height: number);
|
|
10
|
+
/**
|
|
11
|
+
* Get the underlying WebGL rendering context
|
|
12
|
+
*/
|
|
13
|
+
getGLContext(): WebGLRenderingContext;
|
|
14
|
+
/**
|
|
15
|
+
* Get the rendering context
|
|
16
|
+
*/
|
|
17
|
+
getRenderingContext(): RenderingContext;
|
|
18
|
+
/**
|
|
19
|
+
* Get current width
|
|
20
|
+
*/
|
|
21
|
+
getWidth(): number;
|
|
22
|
+
/**
|
|
23
|
+
* Get current height
|
|
24
|
+
*/
|
|
25
|
+
getHeight(): number;
|
|
26
|
+
/**
|
|
27
|
+
* Get viewport dimensions
|
|
28
|
+
*/
|
|
29
|
+
getViewport(): {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Check if running in browser
|
|
35
|
+
*/
|
|
36
|
+
isBrowser(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Resize the graphics device
|
|
39
|
+
*/
|
|
40
|
+
resize(width: number, height: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Clear the rendering surface
|
|
43
|
+
*/
|
|
44
|
+
clear(color?: {
|
|
45
|
+
r: number;
|
|
46
|
+
g: number;
|
|
47
|
+
b: number;
|
|
48
|
+
a: number;
|
|
49
|
+
}): void;
|
|
50
|
+
/**
|
|
51
|
+
* Present the rendered frame
|
|
52
|
+
*/
|
|
53
|
+
present(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Cleanup and release resources
|
|
56
|
+
*/
|
|
57
|
+
dispose(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Create a shader program
|
|
60
|
+
* @param vertexSource Vertex shader source code
|
|
61
|
+
* @param fragmentSource Fragment shader source code
|
|
62
|
+
* @returns Compiled and linked shader program
|
|
63
|
+
*/
|
|
64
|
+
createShader(vertexSource: string, fragmentSource: string): Shader;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=grahpic-device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grahpic-device.d.ts","sourceRoot":"","sources":["../../../src/core/grahpic-device.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAmB;gBAEtB,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IASzC;;OAEG;IACH,YAAY,IAAI,qBAAqB;IAIrC;;OAEG;IACH,mBAAmB,IAAI,gBAAgB;IAIvC;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,WAAW,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAIhD;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI3C;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAInE;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;;;;OAKG;IACH,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM;CAQnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { IResourceLoader } from './resource-loader';
|
|
2
|
+
/**
|
|
3
|
+
* Environment type enumeration
|
|
4
|
+
*/
|
|
5
|
+
export declare enum Environment {
|
|
6
|
+
/** Browser environment (DOM APIs available) */
|
|
7
|
+
BROWSER = "browser",
|
|
8
|
+
/** Node.js environment (file system APIs available) */
|
|
9
|
+
NODE = "node",
|
|
10
|
+
/** Unknown environment */
|
|
11
|
+
UNKNOWN = "unknown"
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resource loader factory configuration
|
|
15
|
+
*/
|
|
16
|
+
export interface ResourceLoaderFactoryOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Force a specific environment (useful for testing)
|
|
19
|
+
* If not specified, the factory will auto-detect the environment
|
|
20
|
+
*/
|
|
21
|
+
forceEnvironment?: Environment;
|
|
22
|
+
/**
|
|
23
|
+
* Base URL for browser resource loader
|
|
24
|
+
*/
|
|
25
|
+
baseUrl?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Request timeout for browser resource loader (in milliseconds)
|
|
28
|
+
*/
|
|
29
|
+
timeout?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Base directory for Node.js resource loader
|
|
32
|
+
*/
|
|
33
|
+
baseDir?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Factory class for creating resource loaders
|
|
37
|
+
* Automatically detects the runtime environment and creates the appropriate loader
|
|
38
|
+
*/
|
|
39
|
+
export declare class ResourceLoaderFactory {
|
|
40
|
+
/**
|
|
41
|
+
* Detect the current runtime environment
|
|
42
|
+
* @returns The detected environment type
|
|
43
|
+
*/
|
|
44
|
+
static detectEnvironment(): Environment;
|
|
45
|
+
/**
|
|
46
|
+
* Check if the current environment is a browser
|
|
47
|
+
* @returns true if running in a browser
|
|
48
|
+
*/
|
|
49
|
+
static isBrowser(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Check if the current environment is Node.js
|
|
52
|
+
* @returns true if running in Node.js
|
|
53
|
+
*/
|
|
54
|
+
static isNode(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Create a resource loader for the current environment
|
|
57
|
+
* @param options Optional factory configuration
|
|
58
|
+
* @returns A resource loader instance appropriate for the current platform
|
|
59
|
+
* @throws Error if the environment is not supported
|
|
60
|
+
*/
|
|
61
|
+
static create(options?: ResourceLoaderFactoryOptions): Promise<IResourceLoader>;
|
|
62
|
+
/**
|
|
63
|
+
* Create a browser resource loader
|
|
64
|
+
* @param options Optional factory configuration
|
|
65
|
+
* @returns A browser resource loader instance
|
|
66
|
+
*/
|
|
67
|
+
static createBrowserLoader(options?: ResourceLoaderFactoryOptions): Promise<IResourceLoader>;
|
|
68
|
+
/**
|
|
69
|
+
* Create a Node.js resource loader
|
|
70
|
+
* @param options Optional factory configuration
|
|
71
|
+
* @returns A Node.js resource loader instance
|
|
72
|
+
*/
|
|
73
|
+
static createNodeLoader(options?: ResourceLoaderFactoryOptions): Promise<IResourceLoader>;
|
|
74
|
+
/**
|
|
75
|
+
* Create a resource loader with automatic fallback
|
|
76
|
+
* If the preferred loader is not available, falls back to the available loader
|
|
77
|
+
* @param preferredEnvironment Preferred environment
|
|
78
|
+
* @param options Optional factory configuration
|
|
79
|
+
* @returns A resource loader instance
|
|
80
|
+
*/
|
|
81
|
+
static createWithFallback(preferredEnvironment: Environment, options?: ResourceLoaderFactoryOptions): Promise<IResourceLoader>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Convenience function to create a resource loader
|
|
85
|
+
* Shortcut for ResourceLoaderFactory.create()
|
|
86
|
+
* @param options Optional factory configuration
|
|
87
|
+
* @returns A resource loader instance
|
|
88
|
+
*/
|
|
89
|
+
export declare function createResourceLoader(options?: ResourceLoaderFactoryOptions): Promise<IResourceLoader>;
|
|
90
|
+
//# sourceMappingURL=resource-loader-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-loader-factory.d.ts","sourceRoot":"","sources":["../../../src/core/resource-loader-factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;GAEG;AACH,oBAAY,WAAW;IACrB,+CAA+C;IAC/C,OAAO,YAAY;IACnB,uDAAuD;IACvD,IAAI,SAAS;IACb,0BAA0B;IAC1B,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,qBAAqB;IAChC;;;OAGG;IACH,MAAM,CAAC,iBAAiB,IAAI,WAAW;IAsBvC;;;OAGG;IACH,MAAM,CAAC,SAAS,IAAI,OAAO;IAI3B;;;OAGG;IACH,MAAM,CAAC,MAAM,IAAI,OAAO;IAIxB;;;;;OAKG;WACU,MAAM,CAAC,OAAO,CAAC,EAAE,4BAA4B,GAAG,OAAO,CAAC,eAAe,CAAC;IAuBrF;;;;OAIG;WACU,mBAAmB,CAC9B,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,eAAe,CAAC;IAQ3B;;;;OAIG;WACU,gBAAgB,CAC3B,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,eAAe,CAAC;IAQ3B;;;;;;OAMG;WACU,kBAAkB,CAC7B,oBAAoB,EAAE,WAAW,EACjC,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,eAAe,CAAC;CAS5B;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,eAAe,CAAC,CAE1B"}
|