graphicsdriver/opengl: Use non-cgo gl package on Windows (#171)

This is a temporal fix until go-gl/glow#102 is applied.
This commit is contained in:
Hajime Hoshi 2018-12-09 02:35:13 +09:00
parent 65294f2e24
commit e8a1be7748
13 changed files with 49721 additions and 3 deletions

1
go.mod
View File

@ -1,7 +1,6 @@
module github.com/hajimehoshi/ebiten
require (
github.com/go-gl/gl v0.0.0-20180407155706-68e253793080
github.com/go-gl/glfw v0.0.0-20181008143348-547915429f42
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/gopherjs/gopherwasm v1.0.1

View File

@ -23,9 +23,8 @@ import (
"errors"
"fmt"
"github.com/go-gl/gl/v2.1/gl"
"github.com/hajimehoshi/ebiten/internal/graphics"
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl/gl"
"github.com/hajimehoshi/ebiten/internal/mainthread"
)

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Eric Woroshow
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,3 @@
This package is basically same as `github.com/go-gl/gl`, but generated from `github.com/hajimehoshi/glow`'s `nocgo` branch. This enables to remove dependencies on Cgo on Windows.
Now we are working on commiting this 'no-cgo' change to the official gl package. See https://github.com/go-gl/glow/pull/102.

View File

@ -0,0 +1,111 @@
// +build !windows
// Code generated by glow (https://github.com/go-gl/glow). DO NOT EDIT.
package gl
import (
"fmt"
"reflect"
"strings"
"unsafe"
)
// #include <stdlib.h>
import "C"
// Ptr takes a slice or pointer (to a singular scalar value or the first
// element of an array or slice) and returns its GL-compatible address.
//
// For example:
//
// var data []uint8
// ...
// gl.TexImage2D(gl.TEXTURE_2D, ..., gl.UNSIGNED_BYTE, gl.Ptr(&data[0]))
func Ptr(data interface{}) unsafe.Pointer {
if data == nil {
return unsafe.Pointer(nil)
}
var addr unsafe.Pointer
v := reflect.ValueOf(data)
switch v.Type().Kind() {
case reflect.Ptr:
e := v.Elem()
switch e.Kind() {
case
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
addr = unsafe.Pointer(e.UnsafeAddr())
default:
panic(fmt.Errorf("unsupported pointer to type %s; must be a slice or pointer to a singular scalar value or the first element of an array or slice", e.Kind()))
}
case reflect.Uintptr:
addr = unsafe.Pointer(v.Pointer())
case reflect.Slice:
addr = unsafe.Pointer(v.Index(0).UnsafeAddr())
default:
panic(fmt.Errorf("unsupported type %s; must be a slice or pointer to a singular scalar value or the first element of an array or slice", v.Type()))
}
return addr
}
// PtrOffset takes a pointer offset and returns a GL-compatible pointer.
// Useful for functions such as glVertexAttribPointer that take pointer
// parameters indicating an offset rather than an absolute memory address.
func PtrOffset(offset int) unsafe.Pointer {
return unsafe.Pointer(uintptr(offset))
}
// Str takes a null-terminated Go string and returns its GL-compatible address.
// This function reaches into Go string storage in an unsafe way so the caller
// must ensure the string is not garbage collected.
func Str(str string) *uint8 {
if !strings.HasSuffix(str, "\x00") {
panic("str argument missing null terminator: " + str)
}
header := (*reflect.StringHeader)(unsafe.Pointer(&str))
return (*uint8)(unsafe.Pointer(header.Data))
}
// GoStr takes a null-terminated string returned by OpenGL and constructs a
// corresponding Go string.
func GoStr(cstr *uint8) string {
return C.GoString((*C.char)(unsafe.Pointer(cstr)))
}
// Strs takes a list of Go strings (with or without null-termination) and
// returns their C counterpart.
//
// The returned free function must be called once you are done using the strings
// in order to free the memory.
//
// If no strings are provided as a parameter this function will panic.
func Strs(strs ...string) (cstrs **uint8, free func()) {
if len(strs) == 0 {
panic("Strs: expected at least 1 string")
}
// Allocate a contiguous array large enough to hold all the strings' contents.
n := 0
for i := range strs {
n += len(strs[i])
}
data := C.malloc(C.size_t(n))
// Copy all the strings into data.
dataSlice := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(data),
Len: n,
Cap: n,
}))
css := make([]*uint8, len(strs)) // Populated with pointers to each string.
offset := 0
for i := range strs {
copy(dataSlice[offset:offset+len(strs[i])], strs[i][:]) // Copy strs[i] into proper data location.
css[i] = (*uint8)(unsafe.Pointer(&dataSlice[offset])) // Set a pointer to it.
offset += len(strs[i])
}
return (**uint8)(&css[0]), func() { C.free(data) }
}

View File

@ -0,0 +1,109 @@
// +build windows
// Code generated by glow (https://github.com/go-gl/glow). DO NOT EDIT.
package gl
import (
"fmt"
"reflect"
"runtime"
"strings"
"unsafe"
)
// Ptr takes a slice or pointer (to a singular scalar value or the first
// element of an array or slice) and returns its GL-compatible address.
//
// For example:
//
// var data []uint8
// ...
// gl.TexImage2D(gl.TEXTURE_2D, ..., gl.UNSIGNED_BYTE, gl.Ptr(&data[0]))
func Ptr(data interface{}) unsafe.Pointer {
if data == nil {
return unsafe.Pointer(nil)
}
var addr unsafe.Pointer
v := reflect.ValueOf(data)
switch v.Type().Kind() {
case reflect.Ptr:
e := v.Elem()
switch e.Kind() {
case
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
addr = unsafe.Pointer(e.UnsafeAddr())
default:
panic(fmt.Errorf("unsupported pointer to type %s; must be a slice or pointer to a singular scalar value or the first element of an array or slice", e.Kind()))
}
case reflect.Uintptr:
addr = unsafe.Pointer(v.Pointer())
case reflect.Slice:
addr = unsafe.Pointer(v.Index(0).UnsafeAddr())
default:
panic(fmt.Errorf("unsupported type %s; must be a slice or pointer to a singular scalar value or the first element of an array or slice", v.Type()))
}
return addr
}
// PtrOffset takes a pointer offset and returns a GL-compatible pointer.
// Useful for functions such as glVertexAttribPointer that take pointer
// parameters indicating an offset rather than an absolute memory address.
func PtrOffset(offset int) unsafe.Pointer {
return unsafe.Pointer(uintptr(offset))
}
// Str takes a null-terminated Go string and returns its GL-compatible address.
// This function reaches into Go string storage in an unsafe way so the caller
// must ensure the string is not garbage collected.
func Str(str string) *uint8 {
if !strings.HasSuffix(str, "\x00") {
panic("str argument missing null terminator: " + str)
}
header := (*reflect.StringHeader)(unsafe.Pointer(&str))
return (*uint8)(unsafe.Pointer(header.Data))
}
// GoStr takes a null-terminated string returned by OpenGL and constructs a
// corresponding Go string.
func GoStr(cstr *uint8) string {
str := ""
for {
if *cstr == 0 {
break
}
str += string(*cstr)
cstr = (*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(cstr)) + 1))
}
return str
}
// Strs takes a list of Go strings (with or without null-termination) and
// returns their C counterpart.
//
// The returned free function must be called once you are done using the strings
// in order to free the memory.
//
// If no strings are provided as a parameter this function will panic.
func Strs(strs ...string) (cstrs **uint8, free func()) {
if len(strs) == 0 {
panic("Strs: expected at least 1 string")
}
var pinned []string
var ptrs []*uint8
for _, str := range strs {
if !strings.HasSuffix(str, "\x00") {
str += "\x00"
}
pinned = append(pinned, str)
ptrs = append(ptrs, Str(str))
}
return &ptrs[0], func() {
runtime.KeepAlive(pinned)
pinned = nil
}
}

View File

@ -0,0 +1,33 @@
// +build !windows
// Code generated by glow (https://github.com/go-gl/glow). DO NOT EDIT.
package gl
import "C"
import "unsafe"
type DebugProc func(
source uint32,
gltype uint32,
id uint32,
severity uint32,
length int32,
message string,
userParam unsafe.Pointer)
var userDebugCallback DebugProc
//export glowDebugCallback_gl21
func glowDebugCallback_gl21(
source uint32,
gltype uint32,
id uint32,
severity uint32,
length int32,
message *uint8,
userParam unsafe.Pointer) {
if userDebugCallback != nil {
userDebugCallback(source, gltype, id, severity, length, GoStr(message), userParam)
}
}

View File

@ -0,0 +1,14 @@
// Code generated by glow (https://github.com/go-gl/glow). DO NOT EDIT.
package gl
import "unsafe"
type DebugProc func(
source uint32,
gltype uint32,
id uint32,
severity uint32,
length int32,
message string,
userParam unsafe.Pointer)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
// +build !windows
// Code generated by glow (https://github.com/go-gl/glow). DO NOT EDIT.
// This file implements GlowGetProcAddress for every supported platform. The
// correct version is chosen automatically based on build tags:
//
// darwin: CGL
// linux freebsd: GLX
//
// Use of EGL instead of the platform's default (listed above) is made possible
// via the "egl" build tag.
//
// It is also possible to install your own function outside this package for
// retrieving OpenGL function pointers, to do this see InitWithProcAddrFunc.
package gl
/*
#cgo darwin CFLAGS: -DTAG_DARWIN
#cgo darwin LDFLAGS: -framework OpenGL
#cgo linux freebsd CFLAGS: -DTAG_POSIX
#cgo linux freebsd LDFLAGS: -lGL
#cgo egl CFLAGS: -DTAG_EGL
#cgo egl LDFLAGS: -lEGL
// Check the EGL tag first as it takes priority over the platform's default
// configuration of WGL/GLX/CGL.
#if defined(TAG_EGL)
#include <stdlib.h>
#include <EGL/egl.h>
void* GlowGetProcAddress_gl21(const char* name) {
return eglGetProcAddress(name);
}
#elif defined(TAG_DARWIN)
#include <stdlib.h>
#include <dlfcn.h>
void* GlowGetProcAddress_gl21(const char* name) {
return dlsym(RTLD_DEFAULT, name);
}
#elif defined(TAG_POSIX)
#include <stdlib.h>
#include <GL/glx.h>
void* GlowGetProcAddress_gl21(const char* name) {
return glXGetProcAddress((const GLubyte *) name);
}
#endif
*/
import "C"
import "unsafe"
func getProcAddress(namea string) unsafe.Pointer {
cname := C.CString(namea)
defer C.free(unsafe.Pointer(cname))
return C.GlowGetProcAddress_gl21(cname)
}

View File

@ -0,0 +1,29 @@
// Code generated by glow (https://github.com/go-gl/glow). DO NOT EDIT.
package gl
import (
"syscall"
"unsafe"
)
var (
opengl32 = syscall.NewLazyDLL("opengl32")
wglGetProcAddress = opengl32.NewProc("wglGetProcAddress")
)
func getProcAddress(namea string) unsafe.Pointer {
cname, err := syscall.BytePtrFromString(namea)
if err != nil {
panic(err)
}
if r, _, _ := wglGetProcAddress.Call(uintptr(unsafe.Pointer(cname))); r != 0 {
return unsafe.Pointer(r)
}
p := opengl32.NewProc(namea)
if err := p.Find(); err != nil {
// The proc is not found.
return nil
}
return unsafe.Pointer(p.Addr())
}