#GLU cImport segfaults

1 messages · Page 1 of 1 (latest)

cold mountain
#

Hello! I went back to a project of porting old versions of minecraft to zig and am trying to update it to 0.16.0. It's been successful so far, progress was slightly annoying as I learned all the new Io interactions, but generally ok. Minecraft used GL 1.1 + GLU for its rendering. The GLU import seems to break, unfortunately, and I don't know why. Info below.

#

Crash

Segmentation fault at address 0x1378ac0
???:?:?: 0x1378ac0 in ??? (???)
Unwind error at address `???:0x1378ac0` (unwind info unavailable), remaining frames may be incorrect
???:?:?: 0x7fabe3af60e3 in ??? (/lib/x86_64-linux-gnu/libGLU.so.1)
/home/createsource/git/Minecraft-Zig/src/Textures.zig:43:30: 0x128f05f in loadTexture (RubyDung.zig)
    _ = GLU.gluBuild2DMipmaps(gl.TEXTURE_2D, gl.RGBA, w, h, gl.RGBA, gl.UNSIGNED_BYTE, data);
                             ^
/home/createsource/git/Minecraft-Zig/src/level/Chunk.zig:35:41: 0x1275a85 in new (RubyDung.zig)
        c.texture = Textures.loadTexture(io, file_alloc, "/terrain.png", gl.NEAREST);
                                        ^
/home/createsource/git/Minecraft-Zig/src/level/LevelRenderer.zig:56:56: 0x1276938 in new (RubyDung.zig)
                    const chunk: *Chunk = try Chunk.new(
                                                       ^
/home/createsource/git/Minecraft-Zig/src/RubyDung.zig:162:51: 0x1277da6 in init (RubyDung.zig)
        self.levelRenderer = try LevelRenderer.new(alloc, self.io, self.file_alloc, self.level);
                                                  ^
/home/createsource/git/Minecraft-Zig/src/RubyDung.zig:326:27: 0x1279d93 in main (RubyDung.zig)
    rd = try RubyDung.init(alloc);
                          ^
/home/createsource/.cache/zig/p/N-V-__8AAFFSVRWqblwBIcA-Yqv-u7sbjsJoww8K0mWaHbmJ/lib/std/start.zig:698:59: 0x127a2d5 in callMain (std.zig)
    if (fn_info.params.len == 0) return wrapMain(root.main());
                                                          ^
../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7fabe382a1c9 in __libc_start_call_main (../sysdeps/x86/libc-start.c)
../csu/libc-start.c:360:3: 0x7fabe382a28a in __libc_start_main_impl (../sysdeps/x86/libc-start.c)
???:?:?: 0x12b6944 in ??? (???)
Aborted (core dumped)```
#

GLU usage

const GLU = @cImport({
    @cInclude("GL/glu.h");
});

...

    const w: c_int = @intCast(img.width);
    const h: c_int = @intCast(img.height);
    const data: *u8 = &img.data[0];
    _ = GLU.gluBuild2DMipmaps(gl.TEXTURE_2D, gl.RGBA, w, h, gl.RGBA, gl.UNSIGNED_BYTE, data);
#

build.zig


const exe = b.addExecutable(.{
    .name = "minecraft_zig",
    .root_module = b.createModule(.{
        .root_source_file = b.path("src/RubyDung.zig"),
        .target = target,
        .optimize = optimize,
        .imports = &.{
            // Here "foo" is the name you will use in your source code to
            // import this module (e.g. `@import("foo")`). The name is
            // repeated because you are allowed to rename your imports, which
            // can be extremely useful in case of collisions (which can happen
            // importing modules from different packages).
            .{ .name = "zstbi", .module = b.dependency("zstbi", .{}).module("root") },
            .{ .name = "zgl", .module = b.dependency("zopengl", .{}).module("root") },
            .{ .name = "zglfw", .module = b.dependency("zglfw", .{}).module("glfw") },
        },
        .link_libc = true,
    }),
});

if (target.result.os.tag == .windows) {
    exe.root_module.addIncludePath(b.path("./include/"));
    exe.root_module.addLibraryPath(b.path("./lib/"));

    const glu = b.addTranslateC(.{
        .root_source_file = b.path("include/GL/glu.h"),
        .target = target,
        .optimize = optimize,
        .link_libc = true,
    });
    exe.root_module.addImport("glu", glu.createModule());

    exe.root_module.linkSystemLibrary("glfw3", .{});
    exe.root_module.linkSystemLibrary("opengl32", .{});
    exe.root_module.linkSystemLibrary("glu32", .{});
    exe.root_module.linkSystemLibrary("gdi32", .{});
    exe.root_module.linkSystemLibrary("shlwapi", .{});
} else {
    exe.root_module.linkSystemLibrary("GLU", .{});
    exe.root_module.linkSystemLibrary("GL", .{});
    exe.root_module.linkSystemLibrary("glfw3", .{});
}
#

im on linux so anything to do with windows isnt the focus atm. i wrote this originally on windows but have since moved to linux

wanton ridge
#

in general, when working with OpenGL (or GLU in this case, which uses OpenGL), when there is a segmentation fault it is likely due to invalid state or bad pointers being passed in. I suggest you turn on OpenGL's debugging features if possible as they will often give you more information on what exactly you did wrong

#

rgba (gl.RGBA/GL_RGBA) images have four channels, and unsigned byte (gl.UNSIGNED_BYTE/GL_UNSIGNED_BYTE) means that each of those channels has one byte per pixel. This means that each pixel takes four bytes, and if you have w*h pixels, that implies your pointer should be 4*w*h in size. if it is smaller, this will cause a segfault when the driver attempts to read back the image (it will look out of the bounds of the array, which is illegal)

cold mountain
wanton ridge
#

you already have the header importing properly, otherwise the code wouldn't compile...

cold mountain
#

yeah

wanton ridge
#

but yes, imports can't go out of the root module path, but you're supposed to use the build system instead of @cImport now anyways

cold mountain
#

ok i followed that tutorial

cold mountain
#

i make sure to load the file with 4 components which is RGBA

wanton ridge
#

strange

#

and you call zstbi.init(allocator) with a valid allocator in your code?

cold mountain
#

you bring up an interesting point because

#

its the only allocator i use thats different from the normal one

#

i pass that in as the io allocator

#

maybe it should just be the normal heap allocator

wanton ridge
#

io allocator should be good

cold mountain
#

well zsdtb.init passes in both io and alloc

wanton ridge
#

actually where exactly are you getting this allocator?

cold mountain
#

well unfortunately that didnt work

#

so i was basically doing the std.threaded thing

#

and then stored both the allocator and the io of what i generated

#

and then used those as the inputs to init

#

but i just swapped that out for the heap alloc and that didnt work either

#

this

var threaded = std.Io.Threaded.init(alloc, .{});
self.file_alloc = threaded.allocator;
self.io = threaded.io();
#

idk if i should do it like that or not

wanton ridge
#

i mean i just use the one passed in by init from the main function

cold mountain
#

i tried that too but no dice

wanton ridge
#

do you have any way to check the length of that pointer?

cold mountain
#

woah woah woah

#

w * h != img.data.len

#

what?

#

oh ok it does equal 4 * w * h

#

ok thats intended that works

#

there's no allocation issue

#

how do i enable opengl debugging?

wanton ridge
#

is GL_TEXTURE_2D bound

cold mountain
#

yes

wanton ridge
#

does opengl 1.1 have debugging?

#

if you can request a newer debug context (for testing purposes) then you will definitely be able to enable debugging

cold mountain
#

i can do that

wanton ridge
#

unless you have to use an older extension (forgive me, I'm familiar with much newer versions of gl than 1.1, i don't know if the proper methods are covered by the debugging extension), once you request a context with KHR_debug you should be able to glEnable GL_DEBUG_OUTPUT and GL_DEBUG_OUTPUT_SYNCHRONOUS, and then add a callback using glDebugMessageCallback, then finally use glDebugMessageControl to enable all of the messages

#

unsure if it will catch your error though

cold mountain
#

i see debugMessageCallbackKHR

#

im using zopengl btw

#

oh it supports khrdebug

#

oh i see a few errors

#

the only thing i see thats relevant is

ERROR: GL_INVALID_ENUM error generated. Cannot enable <cap> in the current profile.
source: 33350, type: 33356, id: 1280, severity: 37190, length: 76
wanton ridge
#

you're using gl 1.1 functions right? make sure to enable the compatibility profile

#

bleh messing up my text

cold mountain
#

i did do that yeah

wanton ridge
#

are there any other calls to glEnable?

#

this is probably unrelated to your texture issue though

cold mountain
#

yeah there's plenty