Skip to content

A dangerous function #128

Open
Open
@aabbtree77

Description

@aabbtree77

I stumbled upon one obscurity with gl.BufferData and decided to post this here in case someone else (or future me) hits it.

Suppose we have a simple mesh to be rendered such as the quad whose triangle vertices are

inds := []uint{0 1 2 1 3 2}

Then one uploads this data to the GPU buffer:

var buffID uint32
gl.GenBuffers(1, &buffID)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffID)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(inds)*int(reflect.TypeOf(inds).Elem().Size()),  gl.Ptr(inds), gl.STATIC_DRAW)    

Here len and Elem are used to get the size of inds in bytes automatically. They are needed as the direct reflect.TypeOf(inds).Size() does not work on the slice, it gives a wrong size of 24 bytes (the correct one is 48 due to uint being of 8 bytes here on my machine).

Renderdoc reveals that on the GPU the mesh gets uploaded as

{0 0 1 0 2 0}

which destroys the mesh and the subsequent rendering silently without issuing any compiler warnings or OpenGL errors.

The solution is to change the type from uint, which is on my 64 bit Ubuntu 20.04 is of size 8 bytes, to the type uint32 which is of size 4 bytes.

inds := []uint32{0 1 2 1 3 2}

Everything works fine this way.

Interestingly, the analogous expressions in C++ did not produce any rendering problems on my machine as unsigned int produced by gcc on Ubuntu 20.04 was 4 bytes. Consider this as a warning not to employ those undefined integer sizes such as int and uint with the OpenGL buffer functions that use gl.Ptr or unsafe.Pointer. This is also one more way to get undefined/erroneous behavior/blank screens without any error message.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions