Last active
May 30, 2020 09:43
-
-
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
This file contains hidden or 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
| # | |
| # 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