Skip to content

Instantly share code, notes, and snippets.

@Saqoosha
Created October 16, 2018 02:51
Show Gist options
  • Save Saqoosha/3ad607e05c5e1d60b37a79a6ad0e9635 to your computer and use it in GitHub Desktop.
Save Saqoosha/3ad607e05c5e1d60b37a79a6ad0e9635 to your computer and use it in GitHub Desktop.

Revisions

  1. Saqoosha created this gist Oct 16, 2018.
    169 changes: 169 additions & 0 deletions glfwbgfx.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,169 @@
    #include <GLFW/glfw3.h>
    #define GLFW_EXPOSE_NATIVE_COCOA
    #define GLFW_EXPOSE_NATIVE_NSGL
    #include <GLFW/glfw3native.h>
    #include <bgfx/c99/bgfx.h>
    #include <bgfx/c99/platform.h>
    #include <cglm/cglm.h>
    #include <stdio.h>


    typedef struct color_vertex {
    float m_x;
    float m_y;
    float m_z;
    uint32_t m_abgr;
    } color_vertex_t;

    static color_vertex_t s_cubeVertices[] = {
    {-1.0f, 1.0f, 1.0f, 0xff000000}, {1.0f, 1.0f, 1.0f, 0xff0000ff}, {-1.0f, -1.0f, 1.0f, 0xff00ff00},
    {1.0f, -1.0f, 1.0f, 0xff00ffff}, {-1.0f, 1.0f, -1.0f, 0xffff0000}, {1.0f, 1.0f, -1.0f, 0xffff00ff},
    {-1.0f, -1.0f, -1.0f, 0xffffff00}, {1.0f, -1.0f, -1.0f, 0xffffffff},
    };

    static const uint16_t s_cubeTriList[] = {
    0, 1, 2, // 0
    1, 3, 2, 4, 6, 5, // 2
    5, 6, 7, 0, 2, 4, // 4
    4, 2, 6, 1, 5, 3, // 6
    5, 7, 3, 0, 4, 1, // 8
    4, 5, 1, 2, 3, 6, // 10
    6, 3, 7,
    };


    static void error_callback(int error, const char *description) { fprintf(stderr, "Error: %s\n", description); }

    static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE);
    }

    bgfx_shader_handle_t loadShader(const char *path) {
    FILE *f = fopen(path, "rb");
    fseek(f, 0, SEEK_END);
    size_t size = ftell(f);
    fseek(f, 0, SEEK_SET);
    const bgfx_memory_t *mem = bgfx_alloc(size);
    fread(mem->data, size, 1, f);
    fclose(f);
    return bgfx_create_shader(mem);
    }

    bgfx_program_handle_t loadProgram(const char *vs, const char *fs) {
    bgfx_shader_handle_t vsh = loadShader(vs);
    bgfx_shader_handle_t fsh = loadShader(fs);
    return bgfx_create_program(vsh, fsh, true);
    }

    int main(int argc, char const *argv[]) {
    glfwSetErrorCallback(error_callback);

    if (!glfwInit()) {
    return -1;
    }

    GLFWwindow *window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window) {
    glfwTerminate();
    return -1;
    }

    glfwSetKeyCallback(window, key_callback);

    glfwMakeContextCurrent(window);

    {
    bgfx_platform_data_t pd;
    memset(&pd, 0, sizeof(bgfx_platform_data_t));
    pd.nwh = glfwGetCocoaWindow(window);
    printf("%p\n", pd.nwh);
    bgfx_set_platform_data(&pd);
    }

    bgfx_init_t init;
    bgfx_init_ctor(&init);
    init.type = BGFX_RENDERER_TYPE_OPENGL;
    init.resolution.width = 640;
    init.resolution.height = 480;
    init.resolution.reset = BGFX_RESET_VSYNC;
    bgfx_init(&init);

    bgfx_reset(640, 480, BGFX_RESET_VSYNC, init.resolution.format);
    bgfx_set_debug(BGFX_DEBUG_TEXT);

    bgfx_set_view_clear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x303030ff, 1.0f, 0);

    bgfx_vertex_decl_t decl;
    bgfx_vertex_decl_begin(&decl, BGFX_RENDERER_TYPE_NOOP);
    bgfx_vertex_decl_add(&decl, BGFX_ATTRIB_POSITION, 3, BGFX_ATTRIB_TYPE_FLOAT, false, false);
    bgfx_vertex_decl_add(&decl, BGFX_ATTRIB_COLOR0, 4, BGFX_ATTRIB_TYPE_UINT8, true, false);
    bgfx_vertex_decl_end(&decl);

    bgfx_vertex_buffer_handle_t vbh =
    bgfx_create_vertex_buffer(bgfx_copy(s_cubeVertices, sizeof(s_cubeVertices)), &decl, BGFX_BUFFER_NONE);
    bgfx_index_buffer_handle_t ibh =
    bgfx_create_index_buffer(bgfx_copy(s_cubeTriList, sizeof(s_cubeTriList)), BGFX_BUFFER_NONE);
    bgfx_program_handle_t program = loadProgram("build/vs_cubes.bin", "build/fs_cubes.bin");

    float time = 0;

    while (!glfwWindowShouldClose(window)) {
    bgfx_dbg_text_clear(0, false);
    bgfx_dbg_text_printf(0, 1, 0x4f, "HOGGEEEEEE!!");
    bgfx_dbg_text_printf(0, 2, 0x6f, "Description: Initialization and debug text.");

    {
    vec3 eye = {0.0f, 0.0f, -35.0f};
    vec3 center = {0.0f, 0.0f, 0.0f};
    vec3 up = {0, 1, 0};
    mat4 view;
    glm_lookat(eye, center, up, view);

    mat4 proj;
    glm_perspective(glm_rad(60.f), 640.f / 480.f, 0.1f, 100.0f, proj);
    // glm_mat4_print(view, stdout);
    // glm_mat4_print(proj, stdout);
    // fflush(stdout);
    bgfx_set_view_transform(0, view, proj);

    bgfx_set_view_rect(0, 0, 0, 640, 480);
    }
    bgfx_touch(0);

    uint64_t state = BGFX_STATE_WRITE_MASK | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_CULL_CW | BGFX_STATE_MSAA;

    // Submit 11x11 cubes.
    for (uint32_t yy = 0; yy < 11; ++yy) {
    for (uint32_t xx = 0; xx < 11; ++xx) {
    mat4 rotation, translate, mtx;
    glm_euler((vec3){time + xx * 0.21f, time + yy * 0.37f, 0}, rotation);
    glm_translate_make(translate, (vec3){-15.0f + (float)xx * 3.0f, -15.0f + (float)yy * 3.0f, 0});
    glm_mat4_mul(translate, rotation, mtx);

    bgfx_set_transform(mtx, 1);

    bgfx_set_vertex_buffer(0, vbh, 0, UINT32_MAX);
    bgfx_set_index_buffer(ibh, 0, UINT32_MAX);

    bgfx_set_state(state, 0);

    bgfx_submit(0, program, 0, false);
    }
    }

    bgfx_frame(false);

    glfwPollEvents();

    time += 0.005f;
    }

    bgfx_destroy_program(program);
    bgfx_destroy_vertex_buffer(vbh);
    bgfx_destroy_index_buffer(ibh);

    bgfx_shutdown();

    glfwTerminate();
    return 0;
    }
    177 changes: 177 additions & 0 deletions glfwbgfx.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,177 @@
    #include <GLFW/glfw3.h>
    #define GLFW_EXPOSE_NATIVE_COCOA
    #define GLFW_EXPOSE_NATIVE_NSGL
    // #include "bgfx_utils.h"
    #include <GLFW/glfw3native.h>
    #include <bgfx/platform.h>
    #include <bx/file.h>
    #include <bx/math.h>
    #include <bx/readerwriter.h>
    #include <bx/string.h>
    #include <stdio.h>


    struct PosColorVertex {
    float m_x;
    float m_y;
    float m_z;
    uint32_t m_abgr;

    static void init() {
    ms_decl.begin()
    .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
    .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
    .end();
    };

    static bgfx::VertexDecl ms_decl;
    };
    bgfx::VertexDecl PosColorVertex::ms_decl;

    static PosColorVertex s_cubeVertices[] = {
    {-1.0f, 1.0f, 1.0f, 0xff000000}, {1.0f, 1.0f, 1.0f, 0xff0000ff}, {-1.0f, -1.0f, 1.0f, 0xff00ff00},
    {1.0f, -1.0f, 1.0f, 0xff00ffff}, {-1.0f, 1.0f, -1.0f, 0xffff0000}, {1.0f, 1.0f, -1.0f, 0xffff00ff},
    {-1.0f, -1.0f, -1.0f, 0xffffff00}, {1.0f, -1.0f, -1.0f, 0xffffffff},
    };

    static const uint16_t s_cubeTriList[] = {
    0, 1, 2, // 0
    1, 3, 2, 4, 6, 5, // 2
    5, 6, 7, 0, 2, 4, // 4
    4, 2, 6, 1, 5, 3, // 6
    5, 7, 3, 0, 4, 1, // 8
    4, 5, 1, 2, 3, 6, // 10
    6, 3, 7,
    };


    static const bgfx::ShaderHandle loadShader(bx::FileReaderI *_reader, const char *_filePath) {
    if (bx::open(_reader, _filePath)) {
    uint32_t size = (uint32_t)bx::getSize(_reader);
    const bgfx::Memory *mem = bgfx::alloc(size + 1);
    bx::read(_reader, mem->data, size);
    bx::close(_reader);
    mem->data[mem->size - 1] = '\0';
    return bgfx::createShader(mem);
    }
    return BGFX_INVALID_HANDLE;
    }

    bgfx::ProgramHandle loadProgram(const char *_vsName, const char *_fsName) {
    bx::FileReader reader;
    bgfx::ShaderHandle vs = loadShader(&reader, "build/vs_cubes.bin");
    bgfx::ShaderHandle fs = loadShader(&reader, "build/fs_cubes.bin");
    return bgfx::createProgram(vs, fs, true);
    }


    static void error_callback(int error, const char *description) { fprintf(stderr, "Error: %s\n", description); }

    static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE);
    }


    int main(int argc, char const *argv[]) {
    glfwSetErrorCallback(error_callback);

    if (!glfwInit()) {
    return -1;
    }

    GLFWwindow *window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window) {
    glfwTerminate();
    return -1;
    }

    glfwSetKeyCallback(window, key_callback);

    glfwMakeContextCurrent(window);

    {
    bgfx::PlatformData pd;
    bx::memSet(&pd, 0, sizeof(pd));
    pd.nwh = glfwGetCocoaWindow(window);
    bgfx::setPlatformData(pd);
    }

    {
    bgfx::Init init;
    init.type = bgfx::RendererType::OpenGL;
    init.resolution.width = 640;
    init.resolution.height = 480;
    init.resolution.reset = BGFX_RESET_VSYNC;
    bgfx::init(init);
    }

    bgfx::reset(640, 480);
    bgfx::setDebug(BGFX_DEBUG_TEXT);

    bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, (uint32_t)0x303030ff, 1.0, 0);

    PosColorVertex::init();

    bgfx::VertexBufferHandle vbh =
    bgfx::createVertexBuffer(bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices)), PosColorVertex::ms_decl);
    bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(bgfx::makeRef(s_cubeTriList, sizeof(s_cubeTriList)));
    bgfx::ProgramHandle program = loadProgram("vs_cubes", "fs_cubes");

    float time = 0;
    while (!glfwWindowShouldClose(window)) {
    bgfx::dbgTextClear();
    bgfx::dbgTextPrintf(0, 1, 0x4f, "HOGEEEeee!!");
    bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text.");

    float at[3] = {0.0f, 0.0f, 0.0f};
    float eye[3] = {0.0f, 0.0f, -35.0f};
    {
    float view[16];
    bx::mtxLookAt(view, eye, at);

    float proj[16];
    bx::mtxProj(proj, 60.0f, 640.0f / 480.0f, 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth);
    bgfx::setViewTransform(0, view, proj);

    // Set view 0 default viewport.
    bgfx::setViewRect(0, 0, 0, 640, 480);
    }
    bgfx::touch(0);

    uint64_t state = BGFX_STATE_WRITE_MASK | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_CULL_CW | BGFX_STATE_MSAA;

    // Submit 11x11 cubes.
    for (uint32_t yy = 0; yy < 11; ++yy) {
    for (uint32_t xx = 0; xx < 11; ++xx) {
    float mtx[16];
    bx::mtxRotateXY(mtx, time + xx * 0.21f, time + yy * 0.37f);
    mtx[12] = -15.0f + float(xx) * 3.0f;
    mtx[13] = -15.0f + float(yy) * 3.0f;
    mtx[14] = 0.0f;
    bgfx::setTransform(mtx);

    bgfx::setVertexBuffer(0, vbh);
    bgfx::setIndexBuffer(ibh);

    bgfx::setState(state);

    bgfx::submit(0, program);
    }
    }

    bgfx::frame();

    glfwPollEvents();

    time += 0.001f;
    }

    bgfx::destroy(program);
    bgfx::destroy(ibh);
    bgfx::destroy(vbh);

    bgfx::shutdown();

    glfwTerminate();
    return 0;
    }
    162 changes: 162 additions & 0 deletions glfwbgfx.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,162 @@
    package main

    /*
    #cgo CFLAGS: -I "/tmp/bgfx/include" -I "/tmp/bx/include"
    #cgo LDFLAGS: -framework Cocoa -framework QuartzCore -framework Metal -lstdc++ /tmp/bgfx/.build/osx64_clang/bin/libbgfxDebug.a /tmp/bgfx/.build/osx64_clang/bin/libbxDebug.a /tmp/bgfx/.build/osx64_clang/bin/libbimgDebug.a
    #include <stdio.h>
    #include <bgfx/c99/platform.h>
    #include <bgfx/c99/bgfx.h>
    void bgfx_dbg_text_print(uint16_t _x, uint16_t _y, uint8_t _attr, const char* text) {
    bgfx_dbg_text_printf(_x, _y, _attr, text);
    }
    */
    import "C"

    import (
    "io/ioutil"
    "runtime"
    "unsafe"

    "github.com/go-gl/glfw/v3.2/glfw"
    "github.com/go-gl/mathgl/mgl32"
    )

    type PosColorVertex struct {
    x, y, z float32
    abgr uint32
    }

    var cubeVertices = []PosColorVertex{
    {-1.0, 1.0, 1.0, 0xff000000},
    {1.0, 1.0, 1.0, 0xff0000ff},
    {-1.0, -1.0, 1.0, 0xff00ff00},
    {1.0, -1.0, 1.0, 0xff00ffff},
    {-1.0, 1.0, -1.0, 0xffff0000},
    {1.0, 1.0, -1.0, 0xffff00ff},
    {-1.0, -1.0, -1.0, 0xffffff00},
    {1.0, -1.0, -1.0, 0xffffffff},
    }
    var cubeTriList = []uint16{
    0, 1, 2, // 0
    1, 3, 2,
    4, 6, 5, // 2
    5, 6, 7,
    0, 2, 4, // 4
    4, 2, 6,
    1, 5, 3, // 6
    5, 7, 3,
    0, 4, 1, // 8
    4, 5, 1,
    2, 3, 6, // 10
    6, 3, 7,
    }

    func init() {
    runtime.LockOSThread()
    }

    func main() {
    err := glfw.Init()
    if err != nil {
    panic(err)
    }
    defer glfw.Terminate()

    window, err := glfw.CreateWindow(640, 480, "goglfw", nil, nil)
    if err != nil {
    panic(err)
    }

    window.MakeContextCurrent()

    var platform C.bgfx_platform_data_t
    platform.nwh = unsafe.Pointer(window.GetCocoaWindow())
    C.bgfx_set_platform_data(&platform)

    var init C.bgfx_init_t
    C.bgfx_init_ctor(&init)
    init._type = C.BGFX_RENDERER_TYPE_OPENGL
    init.resolution.width = 640
    init.resolution.height = 480
    init.resolution.reset = C.BGFX_RESET_VSYNC
    C.bgfx_init(&init)
    defer C.bgfx_shutdown()

    C.bgfx_reset(640, 480, C.BGFX_RESET_VSYNC, init.resolution.format)
    C.bgfx_set_debug(C.BGFX_DEBUG_TEXT)

    C.bgfx_set_view_clear(0, C.BGFX_CLEAR_COLOR|C.BGFX_CLEAR_DEPTH, 0x303030ff, 1.0, 0)

    var decl C.bgfx_vertex_decl_t
    C.bgfx_vertex_decl_begin(&decl, C.BGFX_RENDERER_TYPE_NOOP)
    C.bgfx_vertex_decl_add(&decl, C.BGFX_ATTRIB_POSITION, 3, C.BGFX_ATTRIB_TYPE_FLOAT, false, false)
    C.bgfx_vertex_decl_add(&decl, C.BGFX_ATTRIB_COLOR0, 4, C.BGFX_ATTRIB_TYPE_UINT8, true, false)
    C.bgfx_vertex_decl_end(&decl)

    vbh := C.bgfx_create_vertex_buffer(
    C.bgfx_copy(unsafe.Pointer(&cubeVertices[0]), C.uint32_t(int(unsafe.Sizeof(cubeVertices[0]))*len(cubeVertices))),
    &decl,
    C.BGFX_BUFFER_NONE,
    )
    defer C.bgfx_destroy_vertex_buffer(vbh)

    ibh := C.bgfx_create_index_buffer(
    C.bgfx_copy(unsafe.Pointer(&cubeTriList[0]), C.uint32_t(len(cubeTriList)*2)),
    C.BGFX_BUFFER_NONE,
    )
    defer C.bgfx_destroy_index_buffer(ibh)

    data, err := ioutil.ReadFile("fs_cubes.bin")
    if err != nil {
    panic(err)
    }
    fs := C.bgfx_create_shader(C.bgfx_copy(unsafe.Pointer(&data[0]), C.uint32_t(len(data))))
    defer C.bgfx_destroy_shader(fs)

    data, err = ioutil.ReadFile("vs_cubes.bin")
    if err != nil {
    panic(err)
    }
    vs := C.bgfx_create_shader(C.bgfx_copy(unsafe.Pointer(&data[0]), C.uint32_t(len(data))))
    defer C.bgfx_destroy_shader(vs)

    program := C.bgfx_create_program(vs, fs, C.bool(false))
    defer C.bgfx_destroy_program(program)

    var time float32

    for !window.ShouldClose() {
    C.bgfx_dbg_text_clear(0, false)
    C.bgfx_dbg_text_print(0, 1, 0x4f, C.CString("HOGEEEeee!!"))
    C.bgfx_dbg_text_print(0, 2, 0x6f, C.CString("Description: Initialization and debug text."))

    view := mgl32.LookAt(0, 0, -35, 0, 0, 0, 0, 1, 0)
    projection := mgl32.Perspective(mgl32.DegToRad(60), 640.0/480.0, 0.1, 100)
    C.bgfx_set_view_transform(0, unsafe.Pointer(&view[0]), unsafe.Pointer(&projection[0]))
    C.bgfx_set_view_rect(0, 0, 0, 640, 480)
    C.bgfx_touch(0)

    for yy := 0; yy < 11; yy++ {
    for xx := 0; xx < 11; xx++ {
    mtx := mgl32.Translate3D(-15+float32(xx)*3, -15+float32(yy)*3, 0)
    mtx = mtx.Mul4(mgl32.HomogRotate3DX(time + float32(xx)*0.21))
    mtx = mtx.Mul4(mgl32.HomogRotate3DY(time + float32(yy)*0.37))
    C.bgfx_set_transform(unsafe.Pointer(&mtx[0]), 1)

    C.bgfx_set_vertex_buffer(0, vbh, 0, C.UINT32_MAX)
    C.bgfx_set_index_buffer(ibh, 0, C.UINT32_MAX)

    C.bgfx_set_state(C.uint64_t(C.BGFX_STATE_WRITE_MASK|C.BGFX_STATE_DEPTH_TEST_LESS|C.BGFX_STATE_CULL_CW), 0)

    C.bgfx_submit(0, program, 0, false)
    }
    }

    C.bgfx_frame(false)

    glfw.PollEvents()

    time += 0.005
    }
    }