On Wednesday, December 31, 2014 7:17:44 PM UTC-6, David Crawshaw wrote:
It looks like all of the subtleties have been discussed. Just to
explain my goals when I wrote this package, I sought:

1. a minimal wrapper
2. that lets you do basic things safely and easily
3. that makes it possible to do complex things
4. that works everywhere of interest (mobile)

To meet the first criteria, I had to write off doing anything with
interface{}. There are lots of interesting possibilities, and they can
be built on top of this API.

To meet the second, it is necessary that you can use this package
without importing unsafe. If you search
http://godoc.org/golang.org/x/mobile/gl, you'll see the word unsafe
doesn't appear. That was a design requirement.

Obviously it is OpenGL under the hood, so it is easy enough to
construct some calls with no use of unsafe that will hard lock any
system. So avoiding unsafe is necessary but not sufficient for safety.
It's the best I could think of while meeting the first requirement.

For the third requirement, you can pass in any unsafe pointer you like
to the underlying call. It requires thinking carefully about how to
turn your data into a []byte, but you can do it. And it requires far
less careful thought than actually getting the OpenGL call correct.
Hopefully it will only be done by the few who build higher-level
packages for more general use.

The fourth requirement meant restricting the package to OpenGL ES 2,
as most Android phones do not yet support ES 3. It also meant not
exposing any cgo in the exported symbols, in case some intrepid soul
decided to implement a WebGL version for some non-existent nacl
I was not aware of the nacl/webgl goal.

On Tue, Dec 30, 2014 at 11:43 AM, Bryan Turley <bryan...@gmail.com
<javascript:>> wrote:
On Tuesday, December 30, 2014 9:48:30 AM UTC-6, Matt Harden wrote:

If BufferData were to take an interface{} (or unsafe.Pointer / uintptr
size), then there would be questions as to the exact bytes that end up
the buffer. The Go language makes few guarantees as to the layout of a
struct; as far as I can tell a conforming compiler can even reorder the
fields. The endianness of the target hardware may not be known to the
programmer, nor the size of int, uint and uintptr values. What should
function do if the interface{} passed were a map, channel, function or
pointer, or a struct with a field of one of those types, or a struct
containing one or more slices or embedded structs? Should it consider
non-exported fields of a struct to be part of the data? Besides that,
the considerations that apply to cgo, especially with a moving GC,
(might?) apply here as well.
If you took an interface{} you could use a type switch for the simple types
and the "reflect" package for the non-simple types to determine exactly how
many bytes there are. Using the aforementioned methods would also allow for
weeding out the undesirable types.
In fact those are the main reasons why interface{} is safer than void*.
A slice is a pointer and two lengths, using uintptr/unsafe.Pointer and one
length is also enough.
In the case of unsafe.Pointer + size the exact bytes that should end up in
the buffer is size bytes starting at the unsafe.Pointer... It is called
unsafe for a reason.
Once you cross go into c you have forfeit some of your safety.

With opengl if the endianness of the gpu is different from the host it is
generally the driver or gpu's problem.
There is some endian stuff in the image upload/download funcs.
I don't know of a single CPU that can handle all of the (sometimes bizarre)
floating point formats used by opengl (and possibly natively by the GPU), it
goes beyond endianness.
I don't even know how to express them in a go-like way.
unsigned float10
unsigned float11 (normally crammed into 32bits as 11-11-10 or 10-11-11)
float3x9_5 (3 9bit fractional parts, one shared 5bit exponent crammed into
There are many caveats, which would all be hidden from the programmer
behind a simple-looking interface{} parameter. It's much better that
programmer has to make the data layout explicit by building a []byte.

One good way to encode data in a []byte is to use binary.Write along
bytes.Buffer. These make the endianness, padding etc. explicit.
That is not something I would use in a renderer's inner loop. They are
something I would use outside of time critical loops but not with data for
For inner loops pre-allocate everything and be simple.
Go is statically compiled for the same arch that the driver was, if you use
the goofy gl types you have to deal with it yourself even in C.

If using interleaved vertex arrays a simple []struct backed by C memory is
very efficient and if done correctly safe.

Don't artificially increase complexity.
On Tue Dec 30 2014 at 8:58:06 AM Bryan Turley wrote:

On Tuesday, December 30, 2014 2:43:49 AM UTC-6, Jsor wrote:

They're different approaches. At the sacrifice of requiring an
size input, go-gl allows a pointer to arbitrary structured data. Note
in practice, the go-gl code uses the internal ptr function and can
only take
a uintptr, Go/C pointer, or slice. This saves you from having to use
to convert yourself.

Basically go-gl tries to let the user do things as Go-like as
(minimal to no direct use of unsafe in your own code), whereas
provides a thinner level of wrapping. Note that go-gl also hosts Glow
is an even thinner wrapper where many functions outright take an
Well with []byte it is more like

How would you write a []struct { ... } with File.Write ?
Doesn't seem to have stopped most people using Go.

You could implement a goofy io.Writer/Seeker on top of
Would work even better with glNamedBufferSubData
On Monday, December 29, 2014 11:56:16 PM UTC-8, Thomas Bruyelle
Thanks, I understand and I will follow your advice.
About github.com/go-gl/gl, so the're doing it wrong ?

I actually prefer a uintptr or unsafe.Pointer (like Glow) and a byte
count there, so there is a third method ;)

You received this message because you are subscribed to the Google
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send
email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to golang-nuts...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/d/optout.
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

Discussion Posts


Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 9 of 10 | next ›
Discussion Overview
groupgolang-nuts @
postedDec 29, '14 at 9:22a
activeJan 1, '15 at 5:19a



site design / logo © 2021 Grokbase