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.
bgfx + GLFW in C, C++, Go
#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;
}
#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;
}
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
}
}
@Saqoosha
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment