@footgun/cobalt 0.6.14 → 0.7.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.
- package/CHANGELOG.md +19 -0
- package/bundle.js +1318 -1304
- package/examples/01-primitives/index.html +1 -1
- package/examples/02-sprites/entity-sprite.js +10 -15
- package/examples/02-sprites/hdr.html +321 -0
- package/examples/02-sprites/index.html +21 -120
- package/examples/02-sprites/system-renderer.js +2 -2
- package/examples/03-tiles/index.html +87 -32
- package/examples/03-tiles/system-renderer.js +2 -2
- package/examples/04-overlay/index.html +178 -21
- package/examples/05-bloom/index.html +23 -23
- package/examples/05-bloom/system-renderer.js +2 -2
- package/examples/06-displacement/index.html +20 -112
- package/examples/06-displacement/system-renderer.js +2 -2
- package/examples/08-light/index.html +51 -123
- package/package.json +1 -1
- package/src/cobalt.js +8 -8
- package/src/sprite/public-api.js +57 -177
- package/src/sprite/sprite.js +301 -177
- package/src/sprite/sprite.wgsl +68 -87
- package/src/sprite-hdr/public-api.js +95 -0
- package/src/sprite-hdr/sprite.js +414 -0
- package/src/sprite-hdr/sprite.wgsl +101 -0
- package/src/{sprite → spritesheet}/create-sprite-quads.js +11 -11
- package/src/{sprite → spritesheet}/read-spritesheet.js +62 -28
- package/src/spritesheet/spritesheet.js +75 -0
- package/src/{tile → tile-hdr}/atlas.js +5 -3
- package/src/{tile → tile-hdr}/tile.js +15 -6
- package/examples/04-overlay/deps.js +0 -1
- package/src/overlay/constants.js +0 -1
- package/src/overlay/overlay.js +0 -343
- package/src/overlay/overlay.wgsl +0 -88
- package/src/sprite/constants.js +0 -1
- package/src/sprite/sorted-binary-insert.js +0 -45
- package/src/sprite/spritesheet.js +0 -215
- /package/examples/02-sprites/{Game.js → Global.js} +0 -0
- /package/examples/03-tiles/{Game.js → Global.js} +0 -0
- /package/examples/05-bloom/{Game.js → Global.js} +0 -0
- /package/examples/06-displacement/{Game.js → Global.js} +0 -0
- /package/examples/08-light/{Game.js → Global.js} +0 -0
- /package/src/{tile → tile-hdr}/tile.wgsl +0 -0
package/src/sprite/public-api.js
CHANGED
|
@@ -1,215 +1,95 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { FLOAT32S_PER_SPRITE } from './constants.js'
|
|
1
|
+
import uuid from '../uuid.js'
|
|
2
|
+
import { vec2, vec4 } from 'wgpu-matrix'
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
// returns a unique identifier for the created sprite
|
|
7
|
-
export function addSprite (cobalt, renderPass, name, position, scale, tint, opacity, rotation
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
copySpriteDataToBuffer(renderPass, spritesheet, insertIdx, name, position, scale, tint, opacity, rotation, zIndex)
|
|
26
|
-
|
|
27
|
-
// shift down all of the sprite indices
|
|
28
|
-
for (const [ spriteId, idx ] of renderPass.spriteIndices)
|
|
29
|
-
if (idx >= insertIdx)
|
|
30
|
-
renderPass.spriteIndices.set(spriteId, idx+1)
|
|
31
|
-
|
|
32
|
-
// store the location of this sprite's data in the renderPass's float32array so that we can
|
|
33
|
-
// reference it later, when we need to remove or update this sprite component
|
|
34
|
-
const spriteId = uuid()
|
|
35
|
-
|
|
36
|
-
renderPass.spriteIndices.set(spriteId, insertIdx)
|
|
37
|
-
renderPass.spriteCount++
|
|
38
|
-
renderPass.dirty = true
|
|
39
|
-
|
|
40
|
-
return spriteId
|
|
6
|
+
export function addSprite (cobalt, renderPass, name, position, scale, tint, opacity, rotation) {
|
|
7
|
+
|
|
8
|
+
const { idByName } = renderPass.refs.spritesheet.data
|
|
9
|
+
|
|
10
|
+
renderPass.data.sprites.push({
|
|
11
|
+
position: vec2.clone(position),
|
|
12
|
+
sizeX: 1, sizeY: 1,
|
|
13
|
+
scale: vec2.clone(scale),
|
|
14
|
+
rotation,
|
|
15
|
+
opacity,
|
|
16
|
+
tint: vec4.clone(tint),
|
|
17
|
+
spriteID: idByName.get(name),
|
|
18
|
+
id: uuid(),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return renderPass.data.sprites.at(-1).id
|
|
41
22
|
}
|
|
42
23
|
|
|
43
24
|
|
|
44
|
-
export function removeSprite (cobalt, renderPass,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
renderPass.spriteIndices.set(spriteId, idx-1)
|
|
52
|
-
|
|
53
|
-
// shift up all the data in spriteData from removeIdx to spriteCount-1
|
|
54
|
-
// https://stackoverflow.com/questions/35563529/how-to-copy-typedarray-into-another-typedarray
|
|
55
|
-
let offset = removeIdx * FLOAT32S_PER_SPRITE
|
|
56
|
-
renderPass.spriteData.set(
|
|
57
|
-
renderPass.spriteData.subarray((removeIdx + 1) * FLOAT32S_PER_SPRITE, renderPass.spriteCount * FLOAT32S_PER_SPRITE),
|
|
58
|
-
offset
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
renderPass.spriteIndices.delete(spriteId)
|
|
62
|
-
renderPass.spriteCount--
|
|
63
|
-
renderPass.dirty = true
|
|
25
|
+
export function removeSprite (cobalt, renderPass, id) {
|
|
26
|
+
for (let i=0; i < renderPass.data.sprites.length; i++) {
|
|
27
|
+
if (renderPass.data.sprites[i].id === id) {
|
|
28
|
+
renderPass.data.sprites.splice(i, 1)
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
}
|
|
64
32
|
}
|
|
65
33
|
|
|
66
34
|
|
|
67
35
|
// remove all sprites
|
|
68
36
|
export function clear (cobalt, renderPass) {
|
|
69
|
-
|
|
70
|
-
renderPass.spriteIndices.clear()
|
|
71
|
-
renderPass.spriteCount = 0
|
|
72
|
-
renderPass.instancedDrawCallCount = 0
|
|
73
|
-
renderPass.dirty = true
|
|
37
|
+
renderPass.data.sprites.length = 0
|
|
74
38
|
}
|
|
75
39
|
|
|
76
40
|
|
|
77
|
-
export function setSpriteName (cobalt, renderPass,
|
|
78
|
-
const
|
|
79
|
-
renderPass = renderPass.data
|
|
80
|
-
|
|
81
|
-
const spriteType = spritesheet.locations.indexOf(name)
|
|
41
|
+
export function setSpriteName (cobalt, renderPass, id, name) {
|
|
42
|
+
const sprite = renderPass.data.sprites.find((s) => s.id === id)
|
|
82
43
|
|
|
83
|
-
|
|
84
|
-
|
|
44
|
+
if (!sprite)
|
|
45
|
+
return
|
|
85
46
|
|
|
86
|
-
const
|
|
87
|
-
const offset = spriteIdx * FLOAT32S_PER_SPRITE
|
|
47
|
+
const { idByName } = renderPass.refs.spritesheet.data
|
|
88
48
|
|
|
89
|
-
|
|
90
|
-
renderPass.spriteData[offset+3] = SPRITE_HEIGHT * scale[1]
|
|
91
|
-
|
|
92
|
-
// 12th float is order. lower bits 0-15 are spriteType, bits 16-23 are sprite Z index
|
|
93
|
-
const zIndex = renderPass.spriteData[offset + 11] >> 16 & 0xFF
|
|
94
|
-
|
|
95
|
-
// sortValue is used to sort the sprite by layer, then sprite type
|
|
96
|
-
// zIndex 0-255 (8 bits)
|
|
97
|
-
// spriteType 0-65,535 (16 bits)
|
|
98
|
-
const sortValue = (zIndex << 16 & 0xFF0000) | (spriteType & 0xFFFF)
|
|
99
|
-
renderPass.spriteData[offset+11] = sortValue
|
|
100
|
-
|
|
101
|
-
renderPass.dirty = true
|
|
49
|
+
sprite.spriteID = idByName.get(name)
|
|
102
50
|
}
|
|
103
51
|
|
|
104
52
|
|
|
105
|
-
export function setSpritePosition (cobalt, renderPass,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const offset = spriteIdx * FLOAT32S_PER_SPRITE
|
|
53
|
+
export function setSpritePosition (cobalt, renderPass, id, position) {
|
|
54
|
+
const sprite = renderPass.data.sprites.find((s) => s.id === id)
|
|
55
|
+
if (!sprite)
|
|
56
|
+
return
|
|
110
57
|
|
|
111
|
-
|
|
112
|
-
renderPass.spriteData[offset+1] = position[1]
|
|
113
|
-
|
|
114
|
-
renderPass.dirty = true
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
export function setSpriteTint (cobalt, renderPass, spriteId, tint) {
|
|
119
|
-
renderPass = renderPass.data
|
|
120
|
-
|
|
121
|
-
const spriteIdx = renderPass.spriteIndices.get(spriteId)
|
|
122
|
-
const offset = spriteIdx * FLOAT32S_PER_SPRITE
|
|
123
|
-
|
|
124
|
-
renderPass.spriteData[offset+4] = tint[0]
|
|
125
|
-
renderPass.spriteData[offset+5] = tint[1]
|
|
126
|
-
renderPass.spriteData[offset+6] = tint[2]
|
|
127
|
-
renderPass.spriteData[offset+7] = tint[3]
|
|
128
|
-
|
|
129
|
-
renderPass.dirty = true
|
|
58
|
+
vec2.copy(position, sprite.position)
|
|
130
59
|
}
|
|
131
60
|
|
|
132
61
|
|
|
133
|
-
export function
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const offset = spriteIdx * FLOAT32S_PER_SPRITE
|
|
138
|
-
|
|
139
|
-
renderPass.spriteData[offset+8] = opacity
|
|
62
|
+
export function setSpriteTint (cobalt, renderPass, id, tint) {
|
|
63
|
+
const sprite = renderPass.data.sprites.find((s) => s.id === id)
|
|
64
|
+
if (!sprite)
|
|
65
|
+
return
|
|
140
66
|
|
|
141
|
-
|
|
67
|
+
vec4.copy(tint, sprite.tint)
|
|
142
68
|
}
|
|
143
69
|
|
|
144
70
|
|
|
145
|
-
export function
|
|
146
|
-
|
|
71
|
+
export function setSpriteOpacity (cobalt, renderPass, id, opacity) {
|
|
72
|
+
const sprite = renderPass.data.sprites.find((s) => s.id === id)
|
|
73
|
+
if (!sprite)
|
|
74
|
+
return
|
|
147
75
|
|
|
148
|
-
|
|
149
|
-
const offset = spriteIdx * FLOAT32S_PER_SPRITE
|
|
150
|
-
|
|
151
|
-
renderPass.spriteData[offset+9] = rotation
|
|
152
|
-
renderPass.dirty = true
|
|
76
|
+
sprite.opacity = opacity
|
|
153
77
|
}
|
|
154
78
|
|
|
155
79
|
|
|
156
|
-
export function
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const spriteIdx = renderPass.spriteIndices.get(spriteId)
|
|
161
|
-
const offset = spriteIdx * FLOAT32S_PER_SPRITE
|
|
162
|
-
|
|
163
|
-
const SPRITE_WIDTH = spritesheet.spriteMeta[name].w
|
|
164
|
-
const SPRITE_HEIGHT = spritesheet.spriteMeta[name].h
|
|
165
|
-
|
|
166
|
-
renderPass.spriteData[offset+2] = SPRITE_WIDTH * scale[0]
|
|
167
|
-
renderPass.spriteData[offset+3] = SPRITE_HEIGHT * scale[1]
|
|
80
|
+
export function setSpriteRotation (cobalt, renderPass, id, rotation) {
|
|
81
|
+
const sprite = renderPass.data.sprites.find((s) => s.id === id)
|
|
82
|
+
if (!sprite)
|
|
83
|
+
return
|
|
168
84
|
|
|
169
|
-
|
|
85
|
+
sprite.rotation = rotation
|
|
170
86
|
}
|
|
171
87
|
|
|
172
88
|
|
|
173
|
-
export function
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const spriteIdx = renderPass.spriteIndices.get(spriteId)
|
|
178
|
-
copySpriteDataToBuffer(renderPass, spritesheet, spriteIdx, name, position, scale, tint, opacity, rotation, zIndex)
|
|
179
|
-
|
|
180
|
-
renderPass.dirty = true
|
|
181
|
-
}
|
|
182
|
-
|
|
89
|
+
export function setSpriteScale (cobalt, renderPass, id, scale) {
|
|
90
|
+
const sprite = renderPass.data.sprites.find((s) => s.id === id)
|
|
91
|
+
if (!sprite)
|
|
92
|
+
return
|
|
183
93
|
|
|
184
|
-
|
|
185
|
-
function copySpriteDataToBuffer (renderPass, spritesheet, insertIdx, name, position, scale, tint, opacity, rotation, zIndex) {
|
|
186
|
-
|
|
187
|
-
if (!spritesheet.spriteMeta[name])
|
|
188
|
-
throw new Error(`Sprite name ${name} could not be found in the spritesheet metaData`)
|
|
189
|
-
|
|
190
|
-
const offset = insertIdx * FLOAT32S_PER_SPRITE
|
|
191
|
-
|
|
192
|
-
const SPRITE_WIDTH = spritesheet.spriteMeta[name].w
|
|
193
|
-
const SPRITE_HEIGHT = spritesheet.spriteMeta[name].h
|
|
194
|
-
|
|
195
|
-
// sortValue is used to sort the sprite by layer, then sprite type
|
|
196
|
-
// layer can be a value up to 255 (8 bits)
|
|
197
|
-
// spriteType can be a value up to 65,535 (16 bits)
|
|
198
|
-
const spriteType = spritesheet.locations.indexOf(name)
|
|
199
|
-
const sortValue = (zIndex << 16 & 0xFF0000) | (spriteType & 0xFFFF)
|
|
200
|
-
|
|
201
|
-
renderPass.spriteData[offset] = position[0]
|
|
202
|
-
renderPass.spriteData[offset+1] = position[1]
|
|
203
|
-
renderPass.spriteData[offset+2] = SPRITE_WIDTH * scale[0]
|
|
204
|
-
renderPass.spriteData[offset+3] = SPRITE_HEIGHT * scale[1]
|
|
205
|
-
renderPass.spriteData[offset+4] = tint[0]
|
|
206
|
-
renderPass.spriteData[offset+5] = tint[1]
|
|
207
|
-
renderPass.spriteData[offset+6] = tint[2]
|
|
208
|
-
renderPass.spriteData[offset+7] = tint[3]
|
|
209
|
-
renderPass.spriteData[offset+8] = opacity
|
|
210
|
-
renderPass.spriteData[offset+9] = rotation
|
|
211
|
-
// we used to set emissive intensity per-sprite, but now we use the alpha channel in the emissions texure,
|
|
212
|
-
// which enables us to adjust emission strength on a per-pixel basis. Copying it into the sprite data is a leftover
|
|
213
|
-
//renderPass.spriteData[offset+10] = emissiveIntensity
|
|
214
|
-
renderPass.spriteData[offset+11] = sortValue
|
|
94
|
+
vec2.copy(scale, sprite.scale)
|
|
215
95
|
}
|