comparison examples/E04_input.nim @ 66:44bae6c72834

add: nicer keyboard demo
author Sam <sam@basx.dev>
date Sun, 05 Feb 2023 00:15:48 +0700
parents e766d138cc5d
children 31ccaeee09c9
comparison
equal deleted inserted replaced
65:a44e3ae52139 66:44bae6c72834
1 import std/tables 1 import std/tables
2 import std/enumerate
2 import std/strutils 3 import std/strutils
3 import std/typetraits 4 import std/typetraits
4 import std/times 5 import std/times
5 import std/math 6 import std/math
6 7
30 Vec4([1'f32, 0'f32, 0'f32, 1'f32]), 31 Vec4([1'f32, 0'f32, 0'f32, 1'f32]),
31 Vec4([0.8'f32, 0'f32, 0'f32, 1'f32]), 32 Vec4([0.8'f32, 0'f32, 0'f32, 1'f32]),
32 Vec4([0.8'f32, 0'f32, 0'f32, 1'f32]), 33 Vec4([0.8'f32, 0'f32, 0'f32, 1'f32]),
33 Vec4([0.8'f32, 0'f32, 0'f32, 1'f32]), 34 Vec4([0.8'f32, 0'f32, 0'f32, 1'f32]),
34 ] 35 ]
35 # row width is 15, should sum up 36 # keyboard layout, specifying rows with key widths, negative numbers are empty spaces
36 keyrows = ( 37 keyrows = (
37 [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 3.0], 38 [1.0, -0.6, 1.0, 1.0, 1.0, 1.0, -0.5, 1.0, 1.0, 1.0, 1.0, -0.5, 1.0, 1.0,
38 [1.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.8], 39 1.0, 1.0, -0.1, 1.0, 1.0, 1.0],
39 [1.8, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.2], 40 [1.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.8, -0.1,
40 [2.1, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], 41 1.0, 1.0, 1.0],
41 [3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 3.0], 42 [1.8, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.5, 1.0,
42 [1.5, 1.5, 1.5, 6, 1.5, 1.5, 1.5], 43 1.0, 1.0],
43 ) 44 [2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
44 rowWidth = 900 45 [2.6, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.8, -1.3, 1.0],
45 keyHeight = 50'f32 46 [1.5, 1.5, 1.5, 6, 1.5, 1.5, -1.2, 1.5, -0.1, 1.0, 1.0, 1.0],
47 )
48 keyDimension = 50'f32
46 keyGap = 10'f32 49 keyGap = 10'f32
47 baseColor = Vec4([1'f32, 0'f32, 0'f32, 0'f32]) 50 baseColor = Vec4([1'f32, 0'f32, 0'f32, 0'f32])
48 activeColor = Vec4([1'f32, 1'f32, 1'f32, 0'f32]) 51 activeColor = Vec4([1'f32, 1'f32, 1'f32, 0'f32])
49 keyMap = { 52 keyIndices = [
50 Escape: 0, F1: 1, F2: 2, F3: 3, F4: 4, F5: 5, F6: 6, F7: 7, F8: 8, F9: 9, 53 Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PrintScreen,
51 F10: 10, F11: 11, F12: 12, 54 ScrollLock, Pause,
52 NumberRowExtra1: 13, `1`: 14, `2`: 15, `3`: 16, `4`: 17, `5`: 18, `6`: 19, 55
53 `7`: 20, `8`: 21, `9`: 22, `0`: 23, NumberRowExtra2: 24, 56 NumberRowExtra1, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `0`,
54 NumberRowExtra3: 25, Backspace: 26, 57
55 Tab: 27, Q: 28, W: 29, Key.E: 30, R: 31, T: 32, Key.Y: 33, U: 34, I: 35, O: 36, 58 NumberRowExtra2, NumberRowExtra3, Backspace, Insert, Home, PageUp,
56 P: 37, LetterRow1Extra1: 38, LetterRow1Extra2: 39, LetterRow1Extra3: 40, 59 Tab, Q, W, Key.E, R, T, Key.Y, U, I, O, P, LetterRow1Extra1,
57 CapsLock: 41, A: 42, S: 43, D: 44, F: 45, G: 46, H: 47, J: 48, K: 49, L: 50, 60 LetterRow1Extra2, Delete, End, PageDown,
58 LetterRow2Extra1: 51, LetterRow2Extra2: 52, 61
59 ShiftL: 53, Key.Z: 54, Key.X: 55, C: 56, V: 57, B: 58, N: 59, M: 60, 62 CapsLock, A, S, D, F, G, H, J, K, L, LetterRow2Extra1, LetterRow2Extra2,
60 LetterRow3Extra1: 61, LetterRow3Extra2: 62, LetterRow3Extra3: 63, 63 LetterRow2Extra3, Enter,
61 ShiftR: 64, 64
62 CtrlL: 65, SuperL: 66, AltL: 67, Space: 68, AltR: 69, SuperR: 70, CtrlR: 71, 65 ShiftL, Key.Z, Key.X, C, V, B, N, M, LetterRow3Extra1, LetterRow3Extra2,
63 }.toTable 66 LetterRow3Extra3, ShiftR, Up,
67
68 CtrlL, SuperL, AltL, Space, AltR, SuperR, CtrlR, Left, Down, Right
69 ]
64 70
65 var 71 var
66 pipeline: RenderPipeline[VertexDataA, Uniforms] 72 pipeline: RenderPipeline[VertexDataA, Uniforms]
67 uniforms: Uniforms 73 uniforms: Uniforms
68 scene: Thing 74 scene: Thing
69 keyvertexpos: seq[Vec3] 75 keyvertexpos: seq[Vec3]
70 keyvertexcolor: seq[Vec4] 76 keyvertexcolor: seq[Vec4]
71 keyindices: seq[array[3, uint16]] 77 keymeshindices: seq[array[3, uint16]]
72 rowpos = Vec2([0'f32, 0'f32]) 78 rowpos = Vec2([0'f32, 0'f32])
73 i = 0'u16 79 i = 0'u16
80 firstRow = true
81 rowWidth = 0'f32
74 for row in keyrows.fields: 82 for row in keyrows.fields:
75 let
76 rowSpacePx = rowWidth - (row.len - 1) * keyGap
77 rowSpace = sum(row)
78 for key in row: 83 for key in row:
79 let keySpace = float32((key / rowSpace) * rowSpacePx) 84 let keySpace = float32(keyDimension * key)
80 keyvertexpos.add Vec3([rowpos[0], rowpos[1], 0'f32]) 85 if key > 0:
81 keyvertexpos.add Vec3([rowpos[0] + keySpace, rowpos[1], 0'f32]) 86 if keyIndices[i div 4] == Enter:
82 keyvertexpos.add Vec3([rowpos[0] + keySpace, rowpos[1] + keyHeight, 0'f32]) 87 keyvertexpos.add Vec3([rowpos[0], rowpos[1] - keyDimension - keyGap, 0'f32])
83 keyvertexpos.add Vec3([rowpos[0], rowpos[1] + keyHeight, 0'f32]) 88 keyvertexpos.add Vec3([rowpos[0] + keySpace, rowpos[1] - keyDimension -
84 keyvertexcolor.add [baseColor, baseColor, baseColor, baseColor] 89 keyGap, 0'f32])
85 keyindices.add [i, i + 1, i + 2] 90 else:
86 keyindices.add [i + 2, i + 3, i] 91 keyvertexpos.add Vec3([rowpos[0], rowpos[1], 0'f32])
87 rowpos[0] += keySpace + keyGap 92 keyvertexpos.add Vec3([rowpos[0] + keySpace, rowpos[1], 0'f32])
88 i += 4 93 keyvertexpos.add Vec3([rowpos[0] + keySpace, rowpos[1] + keyDimension, 0'f32])
94 keyvertexpos.add Vec3([rowpos[0], rowpos[1] + keyDimension, 0'f32])
95 keyvertexcolor.add [baseColor, baseColor, baseColor, baseColor]
96 keymeshindices.add [i, i + 1, i + 2]
97 keymeshindices.add [i + 2, i + 3, i]
98 rowpos[0] += keySpace + keyGap
99 i += 4
100 else:
101 rowpos[0] += -keySpace + keyGap
102 if firstRow:
103 rowWidth = rowpos[0]
89 rowpos[0] = 0 104 rowpos[0] = 0
90 rowpos[1] += keyHeight + keyGap 105 rowpos[1] += keyDimension + keyGap * (if firstRow: 2'f32 else: 1'f32)
106 firstRow = false
91 107
92 108
93 proc globalUpdate(engine: var Engine, dt: float32) = 109 proc globalUpdate(engine: var Engine, dt: float32) =
94 uniforms.projection.value = ortho[float32]( 110 uniforms.projection.value = ortho[float32](
95 0'f32, float32(engine.vulkan.frameSize.x), 111 0'f32, float32(engine.vulkan.frameSize.x),
103 winsize = engine.window.size 119 winsize = engine.window.size
104 center = translate3d(float32(winsize[0]) / 2'f32, float32(winsize[1]) / 120 center = translate3d(float32(winsize[0]) / 2'f32, float32(winsize[1]) /
105 2'f32, 0.1'f32) 121 2'f32, 0.1'f32)
106 scene.firstWithName("cursor").transform = mousePos 122 scene.firstWithName("cursor").transform = mousePos
107 scene.firstWithName("keyboard-center").transform = center 123 scene.firstWithName("keyboard-center").transform = center
124 scene.firstWithName("background").transform = scale3d(float32(winsize[0]),
125 float32(winsize[1]), 0'f32)
108 var mesh = Mesh[VertexDataA, uint16](scene.firstWithName("keyboard").parts[0]) 126 var mesh = Mesh[VertexDataA, uint16](scene.firstWithName("keyboard").parts[0])
109 var hadUpdate = false 127 var hadUpdate = false
110 for key, index in keyMap.pairs: 128 for (index, key) in enumerate(keyIndices):
111 if key in engine.input.keysPressed: 129 if key in engine.input.keysPressed:
112 echo "Pressed ", key
113 let baseIndex = index * 4 130 let baseIndex = index * 4
114 mesh.vertexData.color.data[baseIndex + 0] = activeColor 131 mesh.vertexData.color.data[baseIndex + 0] = activeColor
115 mesh.vertexData.color.data[baseIndex + 1] = activeColor 132 mesh.vertexData.color.data[baseIndex + 1] = activeColor
116 mesh.vertexData.color.data[baseIndex + 2] = activeColor 133 mesh.vertexData.color.data[baseIndex + 2] = activeColor
117 mesh.vertexData.color.data[baseIndex + 3] = activeColor 134 mesh.vertexData.color.data[baseIndex + 3] = activeColor
118 hadUpdate = true 135 hadUpdate = true
119 if key in engine.input.keysReleased: 136 if key in engine.input.keysReleased:
120 echo "Released ", key
121 let baseIndex = index * 4 137 let baseIndex = index * 4
122 mesh.vertexData.color.data[baseIndex + 0] = baseColor 138 mesh.vertexData.color.data[baseIndex + 0] = baseColor
123 mesh.vertexData.color.data[baseIndex + 1] = baseColor 139 mesh.vertexData.color.data[baseIndex + 1] = baseColor
124 mesh.vertexData.color.data[baseIndex + 2] = baseColor 140 mesh.vertexData.color.data[baseIndex + 2] = baseColor
125 mesh.vertexData.color.data[baseIndex + 3] = baseColor 141 mesh.vertexData.color.data[baseIndex + 3] = baseColor
129 145
130 146
131 when isMainModule: 147 when isMainModule:
132 var myengine = igniteEngine("Input") 148 var myengine = igniteEngine("Input")
133 149
150 # cursor
134 var cursormesh = new Mesh[VertexDataA, uint16] 151 var cursormesh = new Mesh[VertexDataA, uint16]
135 cursormesh.vertexData = VertexDataA( 152 cursormesh.vertexData = VertexDataA(
136 position: PositionAttribute[Vec3](data: arrow, useOnDeviceMemory: true), 153 position: PositionAttribute[Vec3](data: arrow, useOnDeviceMemory: true),
137 color: ColorAttribute[Vec4](data: arrow_colors), 154 color: ColorAttribute[Vec4](data: arrow_colors),
138 transform: ModelTransformAttribute(data: @[Unit44]), 155 transform: ModelTransformAttribute(data: @[Unit44]),
148 for i in 0 ..< cursormesh.vertexData.position.data.len: 165 for i in 0 ..< cursormesh.vertexData.position.data.len:
149 let pos = Vec3([cursormesh.vertexData.position.data[i][0], 166 let pos = Vec3([cursormesh.vertexData.position.data[i][0],
150 cursormesh.vertexData.position.data[i][1], 0'f32]) 167 cursormesh.vertexData.position.data[i][1], 0'f32])
151 cursormesh.vertexData.position.data[i] = (cursorscale * pos) 168 cursormesh.vertexData.position.data[i] = (cursorscale * pos)
152 169
170 # keyboard
153 var keyboardmesh = new Mesh[VertexDataA, uint16] 171 var keyboardmesh = new Mesh[VertexDataA, uint16]
154 keyboardmesh.indexed = true 172 keyboardmesh.indexed = true
155 keyboardmesh.vertexData = VertexDataA( 173 keyboardmesh.vertexData = VertexDataA(
156 position: PositionAttribute[Vec3](data: keyvertexpos, 174 position: PositionAttribute[Vec3](data: keyvertexpos,
157 useOnDeviceMemory: true), 175 useOnDeviceMemory: true),
158 color: ColorAttribute[Vec4](data: keyvertexcolor), 176 color: ColorAttribute[Vec4](data: keyvertexcolor),
159 transform: ModelTransformAttribute(data: @[Unit44]), 177 transform: ModelTransformAttribute(data: @[Unit44]),
160 ) 178 )
161 keyboardmesh.indices = keyindices 179 keyboardmesh.indices = keymeshindices
180
181 # background
182 var backgroundmesh = new Mesh[VertexDataA, uint16]
183 backgroundmesh.indexed = true
184 backgroundmesh.indices = @[[0'u16, 1'u16, 2'u16], [2'u16, 3'u16, 0'u16]]
185 backgroundmesh.vertexData = VertexDataA(
186 position: PositionAttribute[Vec3](data: @[
187 Vec3([0'f32, 0'f32, 0'f32]),
188 Vec3([1'f32, 0'f32, 0'f32]),
189 Vec3([1'f32, 1'f32, 0'f32]),
190 Vec3([0'f32, 1'f32, 0'f32]),
191 ], useOnDeviceMemory: true),
192 color: ColorAttribute[Vec4](data: @[
193 baseColor * 0.5'f32,
194 baseColor * 0.5'f32,
195 baseColor * 0.5'f32,
196 baseColor * 0.5'f32,
197 ]),
198 transform: ModelTransformAttribute(data: @[Unit44]),
199 )
162 200
163 scene = newThing("scene") 201 scene = newThing("scene")
202 scene.add newThing("background", backgroundmesh)
164 let keyboard = newThing("keyboard", keyboardmesh) 203 let keyboard = newThing("keyboard", keyboardmesh)
165 keyboard.transform = translate3d(-float32(rowWidth) / 2'f32, -float32( 204 keyboard.transform = translate3d(-float32(rowWidth) / 2'f32, -float32(
166 tupleLen(keyRows) * (keyHeight + keyGap) - keyGap) / 2'f32, 0'f32) 205 tupleLen(keyRows) * (keyDimension + keyGap) - keyGap) / 2'f32, 0'f32)
167 scene.add newThing("keyboard-center", keyboard) 206 scene.add newThing("keyboard-center", keyboard)
168 scene.add newThing("cursor", cursormesh) 207 scene.add newThing("cursor", cursormesh)
169 208
170 # upload data, prepare shaders, etc 209 # upload data, prepare shaders, etc
171 const vertexShader = generateVertexShaderCode[VertexDataA, Uniforms](""" 210 const vertexShader = generateVertexShaderCode[VertexDataA, Uniforms]("""