Skip to content

Commit 8dadf25

Browse files
committed
add webgl toggle
1 parent 849446b commit 8dadf25

4 files changed

Lines changed: 63 additions & 14 deletions

File tree

app.js

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { MapboxOverlay as DeckOverlay } from '@deck.gl/mapbox';
33
import { ScatterplotLayer } from '@deck.gl/layers';
44
import maplibregl from 'maplibre-gl';
55
import { webgpuAdapter } from '@luma.gl/webgpu';
6+
import { webgl2Adapter } from '@luma.gl/webgl';
67

78
// --- Configuration ---
89
const INITIAL_VIEW_STATE = {
@@ -30,16 +31,35 @@ const map = new maplibregl.Map({
3031
});
3132

3233
// --- Initialize Deck Context ---
33-
const deckOverlay = new DeckOverlay({
34-
deviceProps: {
35-
adapters: [webgpuAdapter]
36-
},
37-
layers: []
38-
});
34+
let currentBackend = 'webgpu';
35+
let deckOverlay;
36+
37+
function createDeckOverlay(backend) {
38+
return new DeckOverlay({
39+
deviceProps: {
40+
adapters: [backend === 'webgpu' ? webgpuAdapter : webgl2Adapter]
41+
},
42+
layers: []
43+
});
44+
}
3945

46+
deckOverlay = createDeckOverlay(currentBackend);
4047
map.addControl(deckOverlay);
4148
map.addControl(new maplibregl.NavigationControl());
4249

50+
function setBackend(backend) {
51+
if (backend === currentBackend) return;
52+
currentBackend = backend;
53+
map.removeControl(deckOverlay);
54+
deckOverlay = createDeckOverlay(backend);
55+
map.addControl(deckOverlay);
56+
document.getElementById('backend-display').innerText = backend.toUpperCase();
57+
document.getElementById('backend-toggle').innerText =
58+
backend === 'webgpu' ? 'Switch to WebGL' : 'Switch to WebGPU';
59+
// Rebuild layers from raw data on the new device
60+
if (currentData) updateLayer(currentData);
61+
}
62+
4363
// --- Core Logic ---
4464

4565
function updateLayer(data) {
@@ -84,21 +104,22 @@ function updateLayer(data) {
84104
function generatePoints(count) {
85105
const startTime = performance.now();
86106
const positions = new Float32Array(count * 2);
87-
const colors = new Uint8Array(count * 3);
107+
const colors = new Uint8Array(count * 4);
88108

89109
// Use a simpler distribution for speed: full world
90110
for (let i = 0; i < count; i++) {
91111
const i2 = i * 2;
92-
const i3 = i * 3;
112+
const i4 = i * 4;
93113

94114
// Random worldwide coordinates
95115
positions[i2] = (Math.random() - 0.5) * 360;
96116
positions[i2 + 1] = (Math.random() - 0.5) * 170; // Stay within map range
97117

98-
// Random colors
99-
colors[i3] = Math.random() * 255;
100-
colors[i3 + 1] = Math.random() * 255;
101-
colors[i3 + 2] = Math.random() * 255;
118+
// Random colors (RGBA)
119+
colors[i4] = Math.random() * 255;
120+
colors[i4 + 1] = Math.random() * 255;
121+
colors[i4 + 2] = Math.random() * 255;
122+
colors[i4 + 3] = 255;
102123
}
103124

104125
const endTime = performance.now();
@@ -108,11 +129,29 @@ function generatePoints(count) {
108129
length: count,
109130
attributes: {
110131
getPosition: { value: positions, size: 2 },
111-
getFillColor: { value: colors, size: 3 }
132+
getFillColor: { value: colors, size: 4 }
112133
}
113134
};
114135
}
115136

137+
// --- FPS Counter ---
138+
const fpsDisplay = document.getElementById('fps-display');
139+
let fpsFrames = 0;
140+
let fpsLastUpdate = performance.now();
141+
142+
function fpsTick() {
143+
fpsFrames++;
144+
const now = performance.now();
145+
const elapsed = now - fpsLastUpdate;
146+
if (elapsed >= 500) {
147+
fpsDisplay.innerText = Math.round((fpsFrames * 1000) / elapsed);
148+
fpsFrames = 0;
149+
fpsLastUpdate = now;
150+
}
151+
requestAnimationFrame(fpsTick);
152+
}
153+
requestAnimationFrame(fpsTick);
154+
116155
// --- UI Interaction ---
117156

118157
const pointInput = document.getElementById('point-count');
@@ -147,6 +186,11 @@ generateBtn.addEventListener('click', () => {
147186
}, 10);
148187
});
149188

189+
const backendToggle = document.getElementById('backend-toggle');
190+
backendToggle.addEventListener('click', () => {
191+
setBackend(currentBackend === 'webgpu' ? 'webgl' : 'webgpu');
192+
});
193+
150194
const removeBtn = document.getElementById('remove-btn');
151195
removeBtn.addEventListener('click', () => {
152196
currentData = null;

index.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@
262262

263263
<div id="control-panel" class="open">
264264
<div class="drag-handle"></div>
265-
<h2>WebGPU Scatterplot Demo (deck.gl)</h2>
265+
<h2>deck.gl Scatterplot Demo</h2>
266266
<div class="input-group">
267267
<label for="point-count">Generate Points</label>
268268
<input type="text" id="point-count" placeholder="1,000,000" value="1,000,000" inputmode="numeric">
@@ -275,9 +275,12 @@ <h2>WebGPU Scatterplot Demo (deck.gl)</h2>
275275
</svg>
276276
</button>
277277
</div>
278+
<button id="backend-toggle" style="background:#444; margin-bottom:15px;">Switch to WebGL</button>
278279
<div id="status">
280+
<div>Backend: <span id="backend-display">WEBGPU</span></div>
279281
<div>Points: <span id="count-display">0</span></div>
280282
<div>Load time: <span id="time-display">-</span></div>
283+
<div>FPS: <span id="fps-display">-</span></div>
281284
</div>
282285
<p style="font-size: 11px; color: #888; margin-top: 15px; line-height: 1.4;">
283286
Tip: Drag & Drop a JSON file anywhere to load your own data. Format:

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"deck.gl": "^9.0.0",
1414
"@deck.gl/mapbox": "^9.0.0",
1515
"@luma.gl/core": "^9.0.0",
16+
"@luma.gl/webgl": "^9.0.0",
1617
"@luma.gl/webgpu": "^9.0.0",
1718
"maplibre-gl": "^5.0.0"
1819
},

0 commit comments

Comments
 (0)