@@ -3,6 +3,7 @@ import { MapboxOverlay as DeckOverlay } from '@deck.gl/mapbox';
33import { ScatterplotLayer } from '@deck.gl/layers' ;
44import maplibregl from 'maplibre-gl' ;
55import { webgpuAdapter } from '@luma.gl/webgpu' ;
6+ import { webgl2Adapter } from '@luma.gl/webgl' ;
67
78// --- Configuration ---
89const 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 ) ;
4047map . addControl ( deckOverlay ) ;
4148map . 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
4565function updateLayer ( data ) {
@@ -84,21 +104,22 @@ function updateLayer(data) {
84104function 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
118157const 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+
150194const removeBtn = document . getElementById ( 'remove-btn' ) ;
151195removeBtn . addEventListener ( 'click' , ( ) => {
152196 currentData = null ;
0 commit comments