Skip to content

Instantly share code, notes, and snippets.

@vaiorabbit
Last active May 30, 2020 09:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vaiorabbit/3edede824ab0a2281f00032f2f95a650 to your computer and use it in GitHub Desktop.
Save vaiorabbit/3edede824ab0a2281f00032f2f95a650 to your computer and use it in GitHub Desktop.
01_cubes.rb : Ruby-bgfx port of 'cubes.cpp' (WIP). Ref.: https://gist.github.com/vaiorabbit/29acb4ff3b94cefdbcfac3e2787eef50
#
# Ref.: bgfx/examples/01-cubes/cubes.cpp
# https://github.com/vaiorabbit/ruby-opengl/tree/master/sample
#
require 'rmath3d/rmath3d'
require 'opengl'
require 'glfw'
require_relative '../../bindings/ruby/bgfx.rb'
require_relative './logo.rb'
OpenGL.load_lib()
GLFW.load_lib('libglfw.3.4.dylib')
include OpenGL
include GLFW
include RMath3D
Bgfx.load_lib('./libbgfx-shared-libDebug.dylib')
################################################################################
# Press ESC to exit.
key_callback = GLFW::create_callback(:GLFWkeyfun) do |window_handle, key, scancode, action, mods|
if key == GLFW_KEY_ESCAPE && action == GLFW_PRESS
glfwSetWindowShouldClose(window_handle, 1)
end
end
################################################################################
class PosColorVertex < FFI::Struct
@@ms_layout = Bgfx_vertex_layout_t.new
def self.ms_layout
@@ms_layout
end
layout(
:m_x, :float,
:m_y, :float,
:m_z, :float,
:m_abgr, :uint32
)
def self.init()
Bgfx::bgfx_vertex_layout_begin(@@ms_layout, Bgfx::RendererType::Noop)
Bgfx::bgfx_vertex_layout_add(@@ms_layout, Bgfx::Attrib::Position, 3, Bgfx::AttribType::Float, false, false)
Bgfx::bgfx_vertex_layout_add(@@ms_layout, Bgfx::Attrib::Color0, 4, Bgfx::AttribType::Uint8, true, false)
Bgfx::bgfx_vertex_layout_end(@@ms_layout)
end
end
# Ref: Array of Structs https://github.com/ffi/ffi/wiki/Structs
cubeVerticesSrc = [
[-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 ],
]
$s_cubeVertices = FFI::MemoryPointer.new(PosColorVertex, cubeVerticesSrc.length)
cubeVertices = cubeVerticesSrc.length.times.collect do |i|
PosColorVertex.new($s_cubeVertices + i * PosColorVertex.size)
end
cubeVertices.each_with_index do |c, i|
c[:m_x], c[:m_y], c[:m_z], c[:m_abgr] = *cubeVerticesSrc[i]
end
cubeTriListSrc = [
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,
]
$s_cubeTriList = FFI::MemoryPointer.new(:uint16, cubeTriListSrc.length).write_array_of_ushort(cubeTriListSrc)
cubeTriStripSrc = [
0, 1, 2,
3,
7,
1,
5,
0,
4,
2,
6,
7,
4,
5,
]
$s_cubeTriStrip = FFI::MemoryPointer.new(:uint16, cubeTriStripSrc.length).write_array_of_ushort(cubeTriStripSrc)
cubeLineListSrc = [
0, 1,
0, 2,
0, 4,
1, 3,
1, 5,
2, 3,
2, 6,
3, 7,
4, 5,
4, 6,
5, 7,
6, 7,
]
$s_cubeLineList = FFI::MemoryPointer.new(:uint16, cubeLineListSrc.length).write_array_of_ushort(cubeLineListSrc)
cubeLineStripSrc = [
0, 2, 3, 1, 5, 7, 6, 4,
0, 2, 6, 4, 5, 7, 3, 1,
0,
]
$s_cubeLineStrip = FFI::MemoryPointer.new(:uint16, cubeLineStripSrc.length).write_array_of_ushort(cubeLineStripSrc)
cubePointsSrc = [
0, 1, 2, 3, 4, 5, 6, 7
]
$s_cubePoints = FFI::MemoryPointer.new(:uint16, cubePointsSrc.length).write_array_of_ushort(cubePointsSrc)
$s_ptNames = [
"Triangle List",
"Triangle Strip",
"Lines",
"Line Strip",
"Points",
]
$s_ptState = [
0, # Triangles
Bgfx::State_Pt_Tristrip,
Bgfx::State_Pt_Lines,
Bgfx::State_Pt_Linestrip,
Bgfx::State_Pt_Points,
]
def load_shader(name)
runtime_path = "../runtime/"
shader_path = case Bgfx::bgfx_get_renderer_type()
when Bgfx::RendererType::OpenGL
"shaders/glsl/"
when Bgfx::RendererType::Metal
"shaders/metal/"
else
$stderr.puts "You should not be here!"
end
file_path = runtime_path + shader_path + name + ".bin"
shader_binary = IO.read(file_path)
shader_mem = FFI::MemoryPointer.from_string(shader_binary)
handle = Bgfx::bgfx_create_shader(Bgfx::bgfx_make_ref(shader_mem, shader_mem.size))
Bgfx::bgfx_set_shader_name(handle, name, 0x7fffffff) # 0x7fffffff == INT32_MAX
return handle
end
def load_program(vs_name, fs_name)
vsh = load_shader(vs_name)
fsh = fs_name != nil ? load_shader(fs_name) : Bgfx::Bgfx_Invalid_Handle
return Bgfx::bgfx_create_program(vsh, fsh, true)
end
################################################################################
$m_vbh = Bgfx_dynamic_vertex_buffer_handle_t.new
$m_ibh = []
$m_program = Bgfx_shader_handle_t.new
if __FILE__ == $0
glfwInit()
window_width = 1280
window_height = 720
window = glfwCreateWindow( window_width, window_height, "ruby-bgfx : 01-cubes", nil, nil )
glfwMakeContextCurrent( window )
glfwSetKeyCallback( window, key_callback )
nwh = FFI::Pointer.new(:pointer, glfwGetCocoaWindow(window).to_i)
pd = Bgfx_platform_data_t.new
pd[:ndt] = nil
pd[:nwh] = nwh
pd[:context] = nil
pd[:backBuffer] = nil
pd[:backBufferDS] = nil
Bgfx::bgfx_set_platform_data(pd)
init = Bgfx_init_t.new
init[:type] = Bgfx::RendererType::OpenGL
init[:vendorId] = Bgfx::Pci_Id_None
init[:resolution][:width] = window_width
init[:resolution][:height] = window_height
init[:resolution][:reset] = Bgfx::Reset_Vsync
init[:limits][:maxEncoders] = 1
init[:limits][:transientVbSize] = 6<<20
init[:limits][:transientIbSize] = 2<<20
bgfx_init_success = Bgfx::bgfx_init(init)
pp "Failed to initialize Bgfx" unless bgfx_init_success
Bgfx::bgfx_set_debug(Bgfx::Debug_None) # (Bgfx::Debug_Text)
# Bgfx::bgfx_set_debug(Bgfx::Debug_Stats | Bgfx::Debug_Text)
Bgfx::bgfx_set_view_clear(0, Bgfx::Clear_Color|Bgfx::Clear_Depth, 0x303080ff, 1.0, 0)
PosColorVertex.init()
$m_vbh = Bgfx::bgfx_create_vertex_buffer(
Bgfx::bgfx_make_ref($s_cubeVertices, $s_cubeVertices.size),
PosColorVertex.ms_layout,
Bgfx::Buffer_None
)
$m_ibh[0] = Bgfx::bgfx_create_index_buffer(
Bgfx::bgfx_make_ref($s_cubeTriList, $s_cubeTriList.size),
Bgfx::Buffer_None
)
$m_ibh[1] = Bgfx::bgfx_create_index_buffer(
Bgfx::bgfx_make_ref($s_cubeTriStrip, $s_cubeTriStrip.size),
Bgfx::Buffer_None
)
$m_ibh[2] = Bgfx::bgfx_create_index_buffer(
Bgfx::bgfx_make_ref($s_cubeLineList, $s_cubeLineList.size),
Bgfx::Buffer_None
)
$m_ibh[3] = Bgfx::bgfx_create_index_buffer(
Bgfx::bgfx_make_ref($s_cubeLineStrip, $s_cubeLineStrip.size),
Bgfx::Buffer_None
)
$m_ibh[4] = Bgfx::bgfx_create_index_buffer(
Bgfx::bgfx_make_ref($s_cubePoints, $s_cubePoints.size),
Bgfx::Buffer_None
)
$m_program = load_program("vs_cubes", "fs_cubes")
eye = RVec3.new(0.0, 0.0, -35.0)
at = RVec3.new(0.0, 0.0, 0.0)
up = RVec3.new(0.0, 1.0, 0.0)
mtxLookAt = RMtx4.new.lookAtRH( eye, at, up )
view = FFI::MemoryPointer.new(:float, 16).write_array_of_float(mtxLookAt.to_a)
mtxProj = RMtx4.new.perspectiveFovRH( 60.0*Math::PI/180.0, window_width.to_f/window_height.to_f, 0.1, 100.0 ) # TODO bgfx::getCaps()->homogeneousDepth
proj = FFI::MemoryPointer.new(:float, 16).write_array_of_float(mtxProj.to_a)
while glfwWindowShouldClose( window ) == 0
width_ptr = ' ' * 8
height_ptr = ' ' * 8
glfwGetFramebufferSize(window, width_ptr, height_ptr)
width_current = width_ptr.unpack('L')[0]
height_current = height_ptr.unpack('L')[0]
ratio = width_current.to_f / height_current.to_f
if window_width != width_current || window_height != height_current
Bgfx::bgfx_reset(width_current, height_current, Bgfx::Reset_None, Bgfx::TextureFormat::Count)
end
window_width = width_current
window_height = height_current
time = glfwGetTime()
Bgfx::bgfx_set_view_transform(0, view, proj)
Bgfx::bgfx_set_view_rect(0, 0, 0, window_width, window_height)
Bgfx::bgfx_touch(0)
ibh = $m_ibh[0] # TODO use enum
state = 0 | Bgfx::State_Write_R | Bgfx::State_Write_G | Bgfx::State_Write_B | Bgfx::State_Write_A | Bgfx::State_Write_Z | Bgfx::State_Depth_Test_Less | Bgfx::State_Cull_Cw | Bgfx::State_Msaa | $s_ptState[0] # TODO use enum
11.times do |yy|
11.times do |xx|
mtxTransform = RMtx4.new.translation(-15.0 + xx * 3.0, -15.0 + yy * 3.0, 0.0) * RMtx4.new.rotationY(time + yy * 0.37) * RMtx4.new.rotationX(time + xx * 0.21)
mtx = FFI::MemoryPointer.new(:float, 16).write_array_of_float(mtxTransform.to_a)
Bgfx::bgfx_set_transform(mtx, 1)
Bgfx::bgfx_set_vertex_buffer(0, $m_vbh, 0, 0xffffffff) # 0xffffffff == UINT32_MAX
Bgfx::bgfx_set_index_buffer(ibh, 0, 0xffffffff) # 0xffffffff == UINT32_MAX
Bgfx::bgfx_set_state(state, 0)
Bgfx::bgfx_submit(0, $m_program, 0, Bgfx::Discard_All)
end
end
Bgfx::bgfx_frame(false)
glfwSwapBuffers( window )
glfwPollEvents()
end
if bgfx_init_success
Bgfx::bgfx_destroy_program($m_program)
Bgfx::bgfx_destroy_vertex_buffer($m_vbh)
$m_ibh.each do |ibh|
Bgfx::bgfx_destroy_index_buffer(ibh)
end
Bgfx::bgfx_shutdown()
end
glfwDestroyWindow( window )
glfwTerminate()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment