Created
October 16, 2018 02:51
-
-
Save Saqoosha/3ad607e05c5e1d60b37a79a6ad0e9635 to your computer and use it in GitHub Desktop.
bgfx + GLFW in C, C++, Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For matrix operations:
https://github.com/recp/cglm for C,
https://github.com/bkaradzic/bx/blob/master/src/math.cpp for C++,
https://github.com/go-gl/mathgl/ for Go.