twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

conversions_windows.go (2394B)


      1 // SPDX-License-Identifier: MIT
      2 
      3 package gl
      4 
      5 import (
      6 	"fmt"
      7 	"reflect"
      8 	"runtime"
      9 	"strings"
     10 	"unsafe"
     11 )
     12 
     13 // Ptr takes a slice or pointer (to a singular scalar value or the first
     14 // element of an array or slice) and returns its GL-compatible address.
     15 //
     16 // For example:
     17 //
     18 // 	var data []uint8
     19 // 	...
     20 // 	gl.TexImage2D(gl.TEXTURE_2D, ..., gl.UNSIGNED_BYTE, gl.Ptr(&data[0]))
     21 func Ptr(data interface{}) unsafe.Pointer {
     22 	if data == nil {
     23 		return unsafe.Pointer(nil)
     24 	}
     25 	var addr unsafe.Pointer
     26 	switch v := data.(type) {
     27 	case *uint8:
     28 		addr = unsafe.Pointer(v)
     29 	case *uint16:
     30 		addr = unsafe.Pointer(v)
     31 	case *float32:
     32 		addr = unsafe.Pointer(v)
     33 	case []uint8:
     34 		addr = unsafe.Pointer(&v[0])
     35 	case []uint16:
     36 		addr = unsafe.Pointer(&v[0])
     37 	case []float32:
     38 		addr = unsafe.Pointer(&v[0])
     39 	default:
     40 		panic(fmt.Errorf("unsupported type %T; must be a slice or pointer to a singular scalar value or the first element of an array or slice", v))
     41 	}
     42 	return addr
     43 }
     44 
     45 // Str takes a null-terminated Go string and returns its GL-compatible address.
     46 // This function reaches into Go string storage in an unsafe way so the caller
     47 // must ensure the string is not garbage collected.
     48 func Str(str string) *uint8 {
     49 	if !strings.HasSuffix(str, "\x00") {
     50 		panic("str argument missing null terminator: " + str)
     51 	}
     52 	header := (*reflect.StringHeader)(unsafe.Pointer(&str))
     53 	return (*uint8)(unsafe.Pointer(header.Data))
     54 }
     55 
     56 // GoStr takes a null-terminated string returned by OpenGL and constructs a
     57 // corresponding Go string.
     58 func GoStr(cstr *uint8) string {
     59 	str := ""
     60 	for {
     61 		if *cstr == 0 {
     62 			break
     63 		}
     64 		str += string(*cstr)
     65 		cstr = (*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(cstr)) + 1))
     66 	}
     67 	return str
     68 }
     69 
     70 // Strs takes a list of Go strings (with or without null-termination) and
     71 // returns their C counterpart.
     72 //
     73 // The returned free function must be called once you are done using the strings
     74 // in order to free the memory.
     75 //
     76 // If no strings are provided as a parameter this function will panic.
     77 func Strs(strs ...string) (cstrs **uint8, free func()) {
     78 	if len(strs) == 0 {
     79 		panic("Strs: expected at least 1 string")
     80 	}
     81 
     82 	var pinned []string
     83 	var ptrs []*uint8
     84 	for _, str := range strs {
     85 		if !strings.HasSuffix(str, "\x00") {
     86 			str += "\x00"
     87 		}
     88 		pinned = append(pinned, str)
     89 		ptrs = append(ptrs, Str(str))
     90 	}
     91 
     92 	return &ptrs[0], func() {
     93 		runtime.KeepAlive(pinned)
     94 		pinned = nil
     95 	}
     96 }