Search code examples
c#openglopentk

GL.BufferSubData working incorrectly with a 64bit build


I'm using OpenTK for my voxel game engine. Everything is working fine using x86 as platform target, but once I switch to 64bit builds my meshes are all garbled up. I narrowed it down to GL.BufferSubData - as long as I upload only one chunk mesh per VAO (at position 0 obviously) the world renders fine, but as soon as I add more meshes (not at position 0 obviously) to the VAO the glitches start - for me it looks very much looks like new meshes are overwriting previously uploaded meshes.

Here's how I upload my vertices, indices, rgbas and indices:

GL.BindBuffer(BufferTarget.ArrayBuffer, vao.xyzVboId);
GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)data.xyzOffset, sizeof(float) * data.XyzCount, data.xyz);

GL.BindBuffer(BufferTarget.ArrayBuffer, vao.uvVboId);
GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)data.uvOffset, sizeof(float) * data.UvCount, data.uv);

GL.BindBuffer(BufferTarget.ArrayBuffer, vao.rgbaVboId);
GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)data.rgbaOffset, sizeof(byte) * data.RgbaCount, data.rgba);

GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, vao.vboIdIndex);

GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)data.indicesOffset, sizeof(int) * data.indicesCount, data.indices);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

Internally I keep track of the amount data (vertexPosition, indexPosition) and set the xyzOffset, uvOffset, rgbaOffset and indicesOffset accordingly to the amount of inserted vertices and indices.

So apparently my offsets are somehow wrong? But how can this be?

[Edit:] Neither gDebugger nor querying for GL.GetError() shows any error

[Edit2:] This part of code has been running very stable for the last few months, so I don't suspect any mistakes not related to the 64bit build

[Edit3:] Example of how I initialize the VBO

GL.BufferData(BufferTarget.ArrayBuffer, xyzCount, IntPtr.Zero, BufferUsageHint.StaticDraw);

[Edit4:] I've also combed through my code if I do any exotic unsafe pointer arithmetic, which I couldn't find any

[Edit5:] Screenshot: https://i.sstatic.net/aFK9W.jpg

[Edit6:] This is happening on my integrated gpu (intel hd4000), if i tell nvidia to use my GT630M the screen flickers a bunch of times and my game just forcefully exits somehow. The first time it happened nvidia gave me the error message "To many errors"


Solution

  • As it turns out it was caused by 2 bugs

    • When removing meshes the current position was wrongly set by me and I have no idea why it didn't show in the 32bit build

    • I was drawing the meshes using MultiDrawElements, which in OpenTK takes in an int[] array for the index starts. However the parameter is actually of type "const GLvoid * const * indices" - so OpenGL seems to iterate over it in 8 byte increments on 64bit. I made a workaround by doubling the size of my int[] array and leaving every 2nd position empty. Also issue entry on the OpenTK issue tracker: https://github.com/opentk/opentk/issues/423

    With both fixes the messed up drawing on the Intel HD4000 and the flickering on the GT630m is gone.