Not-Nik / raylib-zig

Manually tweaked, auto-generated raylib bindings for zig. https://github.com/raysan5/raylib
MIT License
451 stars 101 forks source link

Can someone check if shaders_mesh_instancing example works from zig? #99

Open nitanmarcel opened 1 month ago

nitanmarcel commented 1 month ago

Can someone check shaders_mesh_instancing example works from zig? I have the following code based on the example above that should draw 10000 cubes at the center of the world, but it doesn't seem to work at all

const std = @import("std");
const rl = @import("raylib");
const gl = @import("rlgl");
const rlmath = @import("raylib-math");

const allocator = std.heap.c_allocator;

const MAX_INSTANCES: usize = 10000;

pub fn main() !void {
    const screen_width = 800;
    const screen_height = 600;

    rl.initWindow(screen_width, screen_height, "Raylib");
    rl.disableCursor();

    var camera = rl.Camera3D{
        .position = rl.Vector3.init(0.0, 0.0, 0.0),
        .target = rl.Vector3.init(0.0, 0.0, 1.0),
        .up = rl.Vector3.init(0.0, 1.0, 0.0),
        .fovy = 45.0,
        .projection = rl.CameraProjection.camera_perspective,
    };

    const cube = rl.genMeshCube(1.0, 1.0, 1.0);

    var transforms = try allocator.alloc(rl.Matrix, MAX_INSTANCES);

    const shader = rl.loadShader("assets/shaders/lighting_instancing.vs", "assets/shaders/lighting.fs");

    const shader_loc_matrix_mvp: usize = @intFromEnum(rl.ShaderLocationIndex.shader_loc_matrix_mvp);
    const shader_loc_vector_view: usize = @intFromEnum(rl.ShaderLocationIndex.shader_loc_vector_view);
    const shader_loc_matrix_model: usize = @intFromEnum(rl.ShaderLocationIndex.shader_loc_matrix_model);

    shader.locs[shader_loc_matrix_mvp] = rl.getShaderLocation(shader, "mvp");
    shader.locs[shader_loc_vector_view] = rl.getShaderLocation(shader, "viewPos");
    shader.locs[shader_loc_matrix_model] = rl.getShaderLocation(shader, "instanceTransform");

    const ambientLoc = rl.getShaderLocation(shader, "ambient");
    const ambientValue: [4]f32 = .{ 0.2, 0.2, 0.2, 1.0 };
    const uniform_type: i32 = @intFromEnum(rl.ShaderUniformDataType.shader_uniform_vec4);
    rl.setShaderValue(shader, ambientLoc, &ambientValue, uniform_type);

    var matInstances = rl.loadMaterialDefault();
    matInstances.shader = shader;
    const material_map_difuse: usize = @intFromEnum(rl.MATERIAL_MAP_DIFFUSE);
    matInstances.maps[material_map_difuse].color = rl.Color.red;

    for (0..MAX_INSTANCES) |i| {
        const translation = rlmath.matrixTranslate(0.0, 0.0, 0.0);
        const axis = rl.Vector3.init(1.0, 2.0, 3.0);
        const angle = 45.0;
        const rotation = rlmath.matrixRotate(axis, angle);
        transforms[i] = rlmath.matrixMultiply(rotation, translation);
    }

    rl.setTargetFPS(60);

    defer {
        allocator.free(transforms);
        rl.unloadMesh(cube);
        rl.unloadMaterial(matInstances);
        rl.unloadShader(shader);
        rl.closeWindow();
    }

    while (!rl.windowShouldClose()) {
        camera.update(rl.CameraMode.camera_free);
        const camPos: [3]f32 = .{ camera.position.x, camera.position.y, camera.position.z };
        const shader_uniform_vec3: i32 = @intFromEnum(rl.ShaderUniformDataType.shader_uniform_vec3);
        rl.setShaderValue(shader, shader.locs[shader_loc_vector_view], &camPos, shader_uniform_vec3);

        rl.beginDrawing();
        rl.clearBackground(rl.Color.ray_white);
        camera.begin();

        defer {
            camera.end();
            rl.endDrawing();
        }

        rl.drawGrid(20, 20);

        gl.rlDisableBackfaceCulling();
        rl.drawMeshInstanced(cube, matInstances, transforms);

        rl.drawFPS(10, 10);
    }
}
ZackeryRSmith commented 2 weeks ago

Hey @nitanmarcel! I'll port the example over sometime soon. For now I have noticed a few issues. The first is rl.setShaderValue expects the uniformType to be a ShaderUniformDataType not an i32. This can be fixed by converting it to an enum before using it in your function call (this can be done with @enumFromInt)

The other issue is how you create your light. Based on the example they use a custom Light struct. In your code you do not do this. You also aren't calling rl.beginMode3D in your code (which they do in the example code).

I also get errors from how you choose to unload a bunch of stuff. This doesn't actually seem to be required and only adds more errors in my case (zig 0.12.0). So you only need to make sure to free transforms.

One more thing. On the latest version of raylib-zig: raylib-math and rlgl are now rl.math and rl.gl. I'll be sure to message you once I try to port the example!

nitanmarcel commented 2 weeks ago

Hey @nitanmarcel! I'll port the example over sometime soon. For now I have noticed a few issues. The first is rl.setShaderValue expects the uniformType to be a ShaderUniformDataType not an i32. This can be fixed by converting it to an enum before using it in your function call (this can be done with @enumFromInt)

The other issue is how you create your light. Based on the example they use a custom Light struct. In your code you do not do this. You also aren't calling rl.beginMode3D in your code (which they do in the example code).

I also get errors from how you choose to unload a bunch of stuff. This doesn't actually seem to be required and only adds more errors in my case (zig 0.12.0). So you only need to make sure to free transforms.

One more thing. On the latest version of raylib-zig: raylib-math and rlgl are now rl.math and rl.gl. I'll be sure to message you once I try to port the example!

camera.begin() calls rl.beginMode3D.

rl.ShaderUniformDataType.shader_uniform_vec3 should have actually been c_uint (it's a cast because some methods don't accept yet structs/enums as their arguments unfortunately). You might be right also about the light, no idea if that's needed tho.

nitanmarcel commented 2 weeks ago

Ah nvm, the parameter for setShaderValue has been already fixed. Anyway the code is before the latest versions xD

https://github.com/Not-Nik/raylib-zig/commit/674e5ada11c116e1eb0313c9121ba1d44797eab7