github.com/thommil/tge-gl@v0.0.0-20190313100017-83d8f10f8fae/gl.go (about) 1 // Copyright (c) 2019 Thomas MILLET. All rights reserved. 2 3 // Package gl defines tge-gl API 4 package gl 5 6 import ( 7 binary "encoding/binary" 8 unsafe "unsafe" 9 10 tge "github.com/thommil/tge" 11 ) 12 13 // Name name of the plugin 14 const Name = "gl" 15 16 var _pluginInstance = &plugin{} 17 var nativeEndian binary.ByteOrder 18 19 func init() { 20 tge.Register(_pluginInstance) 21 22 buf := [2]byte{} 23 *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD) 24 switch buf { 25 case [2]byte{0xAB, 0xCD}: 26 nativeEndian = binary.BigEndian 27 default: 28 nativeEndian = binary.LittleEndian 29 } 30 } 31 32 func (p *plugin) GetName() string { 33 return Name 34 } 35 36 // Byte buffer array singleton, allocate 1mB at startup 37 var byteArrayBuffer = make([]byte, 0) 38 var byteArrayBufferExtendFactor = 1 39 40 func getByteArrayBuffer(size int) []byte { 41 if size > len(byteArrayBuffer) { 42 for (1024 * 1024 * byteArrayBufferExtendFactor) < size { 43 byteArrayBufferExtendFactor++ 44 } 45 byteArrayBuffer = make([]byte, (1024 * 1024 * byteArrayBufferExtendFactor)) 46 } 47 return byteArrayBuffer[:size] 48 } 49 50 // Uint16ToBytes convert uint16 array to byte array 51 // depending on host endianness 52 func Uint16ToBytes(values []uint16) []byte { 53 b := getByteArrayBuffer(2 * len(values)) 54 55 if nativeEndian == binary.LittleEndian { 56 for i, v := range values { 57 u := *(*uint16)(unsafe.Pointer(&v)) 58 b[2*i+0] = byte(u) 59 b[2*i+1] = byte(u >> 8) 60 } 61 } else { 62 for i, v := range values { 63 u := *(*uint16)(unsafe.Pointer(&v)) 64 b[2*i+0] = byte(u >> 8) 65 b[2*i+1] = byte(u) 66 } 67 } 68 69 return b 70 } 71 72 // Uint32ToBytes convert uint32 array to byte array 73 // depending on host endianness 74 func Uint32ToBytes(values []uint32) []byte { 75 b := getByteArrayBuffer(4 * len(values)) 76 77 if nativeEndian == binary.LittleEndian { 78 for i, v := range values { 79 u := *(*uint32)(unsafe.Pointer(&v)) 80 b[2*i+0] = byte(u) 81 b[2*i+1] = byte(u >> 8) 82 b[4*i+2] = byte(u >> 16) 83 b[4*i+3] = byte(u >> 24) 84 } 85 } else { 86 for i, v := range values { 87 u := *(*uint32)(unsafe.Pointer(&v)) 88 b[4*i+0] = byte(u >> 24) 89 b[4*i+1] = byte(u >> 16) 90 b[4*i+2] = byte(u >> 8) 91 b[4*i+3] = byte(u) 92 } 93 } 94 95 return b 96 } 97 98 // Int16ToBytes convert int16 array to byte array 99 // depending on host endianness 100 func Int16ToBytes(values []uint16) []byte { 101 b := getByteArrayBuffer(2 * len(values)) 102 103 if nativeEndian == binary.LittleEndian { 104 for i, v := range values { 105 u := *(*int16)(unsafe.Pointer(&v)) 106 b[2*i+0] = byte(u) 107 b[2*i+1] = byte(u >> 8) 108 } 109 } else { 110 for i, v := range values { 111 u := *(*int16)(unsafe.Pointer(&v)) 112 b[2*i+0] = byte(u >> 8) 113 b[2*i+1] = byte(u) 114 } 115 } 116 117 return b 118 } 119 120 // Int32ToBytes convert int32 array to byte array 121 // depending on host endianness 122 func Int32ToBytes(values []uint32) []byte { 123 b := getByteArrayBuffer(4 * len(values)) 124 125 if nativeEndian == binary.LittleEndian { 126 for i, v := range values { 127 u := *(*int32)(unsafe.Pointer(&v)) 128 b[2*i+0] = byte(u) 129 b[2*i+1] = byte(u >> 8) 130 b[4*i+2] = byte(u >> 16) 131 b[4*i+3] = byte(u >> 24) 132 } 133 } else { 134 for i, v := range values { 135 u := *(*int32)(unsafe.Pointer(&v)) 136 b[4*i+0] = byte(u >> 24) 137 b[4*i+1] = byte(u >> 16) 138 b[4*i+2] = byte(u >> 8) 139 b[4*i+3] = byte(u) 140 } 141 } 142 143 return b 144 } 145 146 // Float32ToBytes convert float32 array to byte array 147 // depending on host endianness 148 func Float32ToBytes(values []float32) []byte { 149 b := getByteArrayBuffer(4 * len(values)) 150 151 if nativeEndian == binary.LittleEndian { 152 for i, v := range values { 153 u := *(*uint32)(unsafe.Pointer(&v)) 154 b[4*i+0] = byte(u) 155 b[4*i+1] = byte(u >> 8) 156 b[4*i+2] = byte(u >> 16) 157 b[4*i+3] = byte(u >> 24) 158 } 159 } else { 160 for i, v := range values { 161 u := *(*uint32)(unsafe.Pointer(&v)) 162 b[4*i+0] = byte(u >> 24) 163 b[4*i+1] = byte(u >> 16) 164 b[4*i+2] = byte(u >> 8) 165 b[4*i+3] = byte(u) 166 } 167 } 168 169 return b 170 } 171 172 // Float64ToBytes convert float64 array to byte array 173 // depending on host endianness 174 func Float64ToBytes(values []float64) []byte { 175 b := getByteArrayBuffer(8 * len(values)) 176 177 if nativeEndian == binary.LittleEndian { 178 for i, v := range values { 179 u := *(*uint64)(unsafe.Pointer(&v)) 180 b[8*i+0] = byte(u) 181 b[8*i+1] = byte(u >> 8) 182 b[8*i+2] = byte(u >> 16) 183 b[8*i+3] = byte(u >> 24) 184 b[8*i+4] = byte(u >> 32) 185 b[8*i+5] = byte(u >> 40) 186 b[8*i+6] = byte(u >> 48) 187 b[8*i+7] = byte(u >> 56) 188 } 189 } else { 190 for i, v := range values { 191 u := *(*uint64)(unsafe.Pointer(&v)) 192 b[8*i+0] = byte(u >> 56) 193 b[8*i+1] = byte(u >> 48) 194 b[8*i+2] = byte(u >> 40) 195 b[8*i+3] = byte(u >> 32) 196 b[8*i+4] = byte(u >> 24) 197 b[8*i+5] = byte(u >> 16) 198 b[8*i+6] = byte(u >> 8) 199 b[8*i+7] = byte(u) 200 } 201 } 202 203 return b 204 } 205 206 // PointerToBytes allows to revover Byte[] from a pointer, useful for ports (ex: G3N) 207 func PointerToBytes(data interface{}, size int) []byte { 208 switch data.(type) { 209 case *uint8: 210 b := getByteArrayBuffer(size) 211 for i := 0; i < size; i++ { 212 b[i] = *(*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*uint8))) + uintptr(i))) 213 } 214 return b 215 case *uint16: 216 b := getByteArrayBuffer(2 * size) 217 if nativeEndian == binary.LittleEndian { 218 for i := 0; i < size; i++ { 219 v := *(*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*uint16))) + uintptr(i*4))) 220 u := *(*uint16)(unsafe.Pointer(&v)) 221 b[2*i+0] = byte(u) 222 b[2*i+1] = byte(u >> 8) 223 } 224 } else { 225 for i := 0; i < size; i++ { 226 v := *(*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*uint16))) + uintptr(i*4))) 227 u := *(*uint16)(unsafe.Pointer(&v)) 228 b[2*i+0] = byte(u >> 8) 229 b[2*i+1] = byte(u) 230 } 231 } 232 return b 233 case *uint32: 234 b := getByteArrayBuffer(4 * size) 235 if nativeEndian == binary.LittleEndian { 236 for i := 0; i < size; i++ { 237 v := *(*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*uint32))) + uintptr(i*4))) 238 u := *(*uint32)(unsafe.Pointer(&v)) 239 b[4*i+0] = byte(u) 240 b[4*i+1] = byte(u >> 8) 241 b[4*i+2] = byte(u >> 16) 242 b[4*i+3] = byte(u >> 24) 243 } 244 } else { 245 for i := 0; i < size; i++ { 246 v := *(*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*uint32))) + uintptr(i*4))) 247 u := *(*uint32)(unsafe.Pointer(&v)) 248 b[4*i+0] = byte(u >> 24) 249 b[4*i+1] = byte(u >> 16) 250 b[4*i+2] = byte(u >> 8) 251 b[4*i+3] = byte(u) 252 } 253 } 254 return b 255 case *float32: 256 b := getByteArrayBuffer(4 * size) 257 if nativeEndian == binary.LittleEndian { 258 for i := 0; i < size; i++ { 259 v := *(*float32)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*float32))) + uintptr(i*4))) 260 u := *(*uint32)(unsafe.Pointer(&v)) 261 b[4*i+0] = byte(u) 262 b[4*i+1] = byte(u >> 8) 263 b[4*i+2] = byte(u >> 16) 264 b[4*i+3] = byte(u >> 24) 265 } 266 } else { 267 for i := 0; i < size; i++ { 268 v := *(*float32)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*float32))) + uintptr(i*4))) 269 u := *(*uint32)(unsafe.Pointer(&v)) 270 b[4*i+0] = byte(u >> 24) 271 b[4*i+1] = byte(u >> 16) 272 b[4*i+2] = byte(u >> 8) 273 b[4*i+3] = byte(u) 274 } 275 } 276 return b 277 case *float64: 278 b := getByteArrayBuffer(8 * size) 279 if nativeEndian == binary.LittleEndian { 280 for i := 0; i < size; i++ { 281 v := *(*float64)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*float64))) + uintptr(i*8))) 282 u := *(*uint64)(unsafe.Pointer(&v)) 283 b[8*i+0] = byte(u) 284 b[8*i+1] = byte(u >> 8) 285 b[8*i+2] = byte(u >> 16) 286 b[8*i+3] = byte(u >> 24) 287 b[8*i+4] = byte(u >> 32) 288 b[8*i+5] = byte(u >> 40) 289 b[8*i+6] = byte(u >> 48) 290 b[8*i+7] = byte(u >> 56) 291 } 292 } else { 293 for i := 0; i < size; i++ { 294 v := *(*float64)(unsafe.Pointer(uintptr(unsafe.Pointer(data.(*float64))) + uintptr(i*8))) 295 u := *(*uint64)(unsafe.Pointer(&v)) 296 b[8*i+0] = byte(u >> 56) 297 b[8*i+1] = byte(u >> 48) 298 b[8*i+2] = byte(u >> 40) 299 b[8*i+3] = byte(u >> 32) 300 b[8*i+4] = byte(u >> 24) 301 b[8*i+5] = byte(u >> 16) 302 b[8*i+6] = byte(u >> 8) 303 b[8*i+7] = byte(u) 304 } 305 } 306 return b 307 } 308 return nil 309 }