Skip to content

Instantly share code, notes, and snippets.

@vaiorabbit
Created June 7, 2020 12:27
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/3ef08afbfbca5dea008cac72c19b173b to your computer and use it in GitHub Desktop.
Save vaiorabbit/3ef08afbfbca5dea008cac72c19b173b to your computer and use it in GitHub Desktop.
imgui_impl_bgfx.rb : Ruby-ImGui ( https://github.com/vaiorabbit/ruby-imgui ) rendering backend written in WIP Ruby-bgfx. Ref.: https://gist.github.com/vaiorabbit/29acb4ff3b94cefdbcfac3e2787eef50
# coding: utf-8
#
# Ref.: bgfx/examples/06-bump/bump.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 './utils.rb'
require_relative 'imgui'
require_relative 'imgui_impl_bgfx'
$imgui_dll_path = case RUBY_PLATFORM
when /mswin|msys|mingw|cygwin/
Dir.pwd + '/' + 'imgui.dll'
when /darwin/
'./imgui.dylib'
when /linux/
'../cimgui_impl_dll/build/imgui.so'
else
raise RuntimeError, "Unknown OS: #{RUBY_PLATFORM}"
end
$glfw_dll_path = case RUBY_PLATFORM
when /mswin|msys|mingw|cygwin/
Dir.pwd + '/' + 'glfw3.dll'
when /darwin/
'./libglfw.dylib'
when /linux/
'./libglfw3.so'
else
raise RuntimeError, "Unknown OS: #{RUBY_PLATFORM}"
end
$bgfx_dll_path = case RUBY_PLATFORM
when /mswin|msys|mingw|cygwin/
Dir.pwd + '/bgfx-shared-libDebug.dll'
when /darwin/
'./libbgfx-shared-libDebug.dylib'
when /linux/
'./libbgfx-shared-libDebug.so'
else
raise RuntimeError, "Unknown OS: #{RUBY_PLATFORM}"
end
OpenGL.load_lib()
GLFW.load_lib($glfw_dll_path)
ImGui.load_lib($imgui_dll_path)
Bgfx.load_lib($bgfx_dll_path)
include OpenGL
include GLFW
include RMath3D
################################################################################
# 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 PosNormalTangentTexcoordVertex < 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_normal, :uint32,
:m_tangent, :uint32,
:m_u, :int16,
:m_v, :int16
)
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::Normal, 4, Bgfx::AttribType::Uint8, true, true)
Bgfx::bgfx_vertex_layout_add(@@ms_layout, Bgfx::Attrib::Tangent, 4, Bgfx::AttribType::Uint8, true, true)
Bgfx::bgfx_vertex_layout_add(@@ms_layout, Bgfx::Attrib::TexCoord0, 2, Bgfx::AttribType::Int16, true, true)
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, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, 1.0), 0, 0, 0 ],
[ 1.0, 1.0, 1.0, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, 1.0), 0, 0x7fff, 0 ],
[-1.0, -1.0, 1.0, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, 1.0), 0, 0, 0x7fff ],
[ 1.0, -1.0, 1.0, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, 1.0), 0, 0x7fff, 0x7fff ],
[-1.0, 1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, -1.0), 0, 0, 0 ],
[ 1.0, 1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, -1.0), 0, 0x7fff, 0 ],
[-1.0, -1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, -1.0), 0, 0, 0x7fff ],
[ 1.0, -1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, 0.0, -1.0), 0, 0x7fff, 0x7fff ],
[-1.0, 1.0, 1.0, BgfxUtils.encode_normal_rgba8( 0.0, 1.0, 0.0), 0, 0, 0 ],
[ 1.0, 1.0, 1.0, BgfxUtils.encode_normal_rgba8( 0.0, 1.0, 0.0), 0, 0x7fff, 0 ],
[-1.0, 1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, 1.0, 0.0), 0, 0, 0x7fff ],
[ 1.0, 1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, 1.0, 0.0), 0, 0x7fff, 0x7fff ],
[-1.0, -1.0, 1.0, BgfxUtils.encode_normal_rgba8( 0.0, -1.0, 0.0), 0, 0, 0 ],
[ 1.0, -1.0, 1.0, BgfxUtils.encode_normal_rgba8( 0.0, -1.0, 0.0), 0, 0x7fff, 0 ],
[-1.0, -1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, -1.0, 0.0), 0, 0, 0x7fff ],
[ 1.0, -1.0, -1.0, BgfxUtils.encode_normal_rgba8( 0.0, -1.0, 0.0), 0, 0x7fff, 0x7fff ],
[ 1.0, -1.0, 1.0, BgfxUtils.encode_normal_rgba8( 1.0, 0.0, 0.0), 0, 0, 0 ],
[ 1.0, 1.0, 1.0, BgfxUtils.encode_normal_rgba8( 1.0, 0.0, 0.0), 0, 0x7fff, 0 ],
[ 1.0, -1.0, -1.0, BgfxUtils.encode_normal_rgba8( 1.0, 0.0, 0.0), 0, 0, 0x7fff ],
[ 1.0, 1.0, -1.0, BgfxUtils.encode_normal_rgba8( 1.0, 0.0, 0.0), 0, 0x7fff, 0x7fff ],
[-1.0, -1.0, 1.0, BgfxUtils.encode_normal_rgba8(-1.0, 0.0, 0.0), 0, 0, 0 ],
[-1.0, 1.0, 1.0, BgfxUtils.encode_normal_rgba8(-1.0, 0.0, 0.0), 0, 0x7fff, 0 ],
[-1.0, -1.0, -1.0, BgfxUtils.encode_normal_rgba8(-1.0, 0.0, 0.0), 0, 0, 0x7fff ],
[-1.0, 1.0, -1.0, BgfxUtils.encode_normal_rgba8(-1.0, 0.0, 0.0), 0, 0x7fff, 0x7fff ],
]
$s_cubeVertices = FFI::MemoryPointer.new(PosNormalTangentTexcoordVertex, cubeVerticesSrc.length)
cubeVertices = cubeVerticesSrc.length.times.collect do |i|
PosNormalTangentTexcoordVertex.new($s_cubeVertices + i * PosNormalTangentTexcoordVertex.size)
end
cubeVertices.each_with_index do |c, i|
c[:m_x], c[:m_y], c[:m_z], c[:m_normal], c[:m_tangent], c[:m_u], c[:m_v] = *cubeVerticesSrc[i]
end
cubeIndicesSrc = [
0, 2, 1,
1, 2, 3,
4, 5, 6,
5, 7, 6,
8, 10, 9,
9, 10, 11,
12, 13, 14,
13, 15, 14,
16, 18, 17,
17, 18, 19,
20, 21, 22,
21, 23, 22,
]
$s_cubeIndices = FFI::MemoryPointer.new(:uint16, cubeIndicesSrc.length).write_array_of_ushort(cubeIndicesSrc)
################################################################################
$m_vbh = nil # Bgfx_dynamic_vertex_buffer_handle_t
$m_ibh = nil # Bgfx_dynamic_index_buffer_handle_t
$m_program = nil # Bgfx_shader_handle_t
$s_texColor = nil # Bgfx_uniform_handle_t
$s_texNormal = nil # Bgfx_uniform_handle_t
$u_lightPosRadius = nil # Bgfx_uniform_handle_t
$u_lightRgbInnerR = nil # Bgfx_uniform_handle_t
$m_numLights = 4 # uint16
$m_textureColor = nil # Bgfx_texture_handle_t
$m_textureNormal = nil # Bgfx_texture_handle_t
if __FILE__ == $0
glfwInit()
window_width = 1280
window_height = 720
window = glfwCreateWindow( window_width, window_height, "ruby-bgfx : 06-bump", nil, nil )
glfwMakeContextCurrent( window )
glfwSetKeyCallback( window, key_callback )
native_window_handle = case RUBY_PLATFORM
when /mswin|msys|mingw|cygwin/
glfwGetWin32Window(window).to_i
when /darwin/
glfwGetCocoaWindow(window).to_i
when /linux/
glfwGetGLXWindow(window)
else
raise RuntimeError, "Unknown OS: #{RUBY_PLATFORM}"
end
nwh = FFI::Pointer.new(:pointer, native_window_handle)
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_Wireframe) # (Bgfx::Debug_Text)
#Bgfx::bgfx_set_debug(Bgfx::Debug_Stats | Bgfx::Debug_Text | Bgfx::Debug_Profiler)
Bgfx::bgfx_set_view_clear(0, Bgfx::Clear_Color|Bgfx::Clear_Depth, 0x303080ff, 1.0, 0)
PosNormalTangentTexcoordVertex.init()
BgfxUtils.calc_tangents($s_cubeVertices, $s_cubeVertices.size / $s_cubeVertices.type_size, PosNormalTangentTexcoordVertex.ms_layout, cubeIndicesSrc)
$m_vbh = Bgfx::bgfx_create_vertex_buffer(
Bgfx::bgfx_make_ref($s_cubeVertices, $s_cubeVertices.size),
PosNormalTangentTexcoordVertex.ms_layout,
Bgfx::Buffer_None
)
$m_ibh = Bgfx::bgfx_create_index_buffer(
Bgfx::bgfx_make_ref($s_cubeIndices, $s_cubeIndices.size),
Bgfx::Buffer_None
)
$s_texColor = Bgfx::bgfx_create_uniform("s_texColor", Bgfx::UniformType::Sampler, -1)
$s_texNormal = Bgfx::bgfx_create_uniform("s_texNormal", Bgfx::UniformType::Sampler, -1)
$u_lightPosRadius = Bgfx::bgfx_create_uniform("u_lightPosRadius", Bgfx::UniformType::Vec4, $m_numLights)
$u_lightRgbInnerR = Bgfx::bgfx_create_uniform("u_lightRgbInnerR", Bgfx::UniformType::Vec4, $m_numLights)
$m_textureColor = BgfxUtils.load_texture("textures/fieldstone-rgba.dds")
$m_textureNormal = BgfxUtils.load_texture("textures/fieldstone-n.dds")
$m_program = BgfxUtils.load_program("vs_bump", "fs_bump")
eye = RVec3.new(0.0, 0.0, -7.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)
ImGui::CreateContext()
ImGui::ImplBgfx_Init()
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()
io = ImGuiIO.new(ImGui::GetIO())
io[:DisplaySize][:x] = window_width
io[:DisplaySize][:y] = window_height
if window_width > 0 && window_height > 0 # TODO
io[:DisplayFramebufferScale][:x] = 1.0
io[:DisplayFramebufferScale][:y] = 1.0
end
io[:DeltaTime] = (1.0/60.0) # TODO
io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional)
io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used)
# TODO UpdateMousePosAndButtons()
# TODO Glfw_UpdateMouseCursor()
ImGui::NewFrame()
ImGui::PushFont(ImGui::ImplBgfx_GetFont())
ImGui::ShowDemoWindow()
ImGui::PopFont()
ImGui::Render()
ImGui::ImplBgfx_RenderDrawData(ImGui::GetDrawData())
Bgfx::bgfx_set_view_transform(0, view, proj)
Bgfx::bgfx_set_view_rect(0, 0, 0, window_width, window_height)
Bgfx::bgfx_touch(0)
light_pos_radius = Array.new(4) { Array.new(4, 0.0) }
$m_numLights.times do |ii|
light_pos_radius[ii][0] = Math.sin( (time*(0.1 + ii*0.17) + ii*(0.5 * Math::PI) * 1.37 ) )*3.0
light_pos_radius[ii][1] = Math.cos( (time*(0.2 + ii*0.29) + ii*(0.5 * Math::PI) * 1.49 ) )*3.0
light_pos_radius[ii][2] = -2.5
light_pos_radius[ii][3] = 3.0
end
Bgfx::bgfx_set_uniform($u_lightPosRadius, light_pos_radius.flatten!.pack("F16"), $m_numLights)
light_rgb_inner_r = [
[ 1.0, 0.7, 0.2, 0.8 ],
[ 0.7, 0.2, 1.0, 0.8 ],
[ 0.2, 1.0, 0.7, 0.8 ],
[ 1.0, 0.4, 0.2, 0.8 ],
]
Bgfx::bgfx_set_uniform($u_lightRgbInnerR, light_rgb_inner_r.flatten!.pack("F16"), $m_numLights)
state = 0 | Bgfx::State_Write_Rgb | Bgfx::State_Write_A | Bgfx::State_Write_Z | Bgfx::State_Depth_Test_Less | Bgfx::State_Msaa
3.times do |yy|
3.times do |xx|
mtxTransform = RMtx4.new.translation(-3.0 + xx * 3.0, -3.0 + yy * 3.0, 0.0) * RMtx4.new.rotationY(time * 0.03 + yy * 0.37) * RMtx4.new.rotationX(time * 0.23 + 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($m_ibh, 0, 0xffffffff) # 0xffffffff == UINT32_MAX
Bgfx::bgfx_set_texture(0, $s_texColor, $m_textureColor, 0xffffffff) # 0xffffffff == UINT32_MAX
Bgfx::bgfx_set_texture(1, $s_texNormal, $m_textureNormal, 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
ImGui::ImplBgfx_Shutdown()
ImGui::DestroyContext(nil)
if bgfx_init_success
Bgfx::bgfx_destroy_uniform($s_texColor)
Bgfx::bgfx_destroy_uniform($s_texNormal)
Bgfx::bgfx_destroy_uniform($u_lightPosRadius)
Bgfx::bgfx_destroy_uniform($u_lightRgbInnerR)
Bgfx::bgfx_destroy_texture($m_textureNormal)
Bgfx::bgfx_destroy_texture($m_textureColor)
Bgfx::bgfx_destroy_program($m_program)
Bgfx::bgfx_destroy_vertex_buffer($m_vbh)
Bgfx::bgfx_destroy_index_buffer($m_ibh)
Bgfx::bgfx_shutdown()
end
glfwDestroyWindow( window )
glfwTerminate()
end
# coding: utf-8
require 'ffi'
require_relative '../../bindings/ruby/bgfx.rb'
require_relative 'imgui'
require_relative 'utils'
module ImGui
# [Not used yet] Structs for type conversion (or type-punning), used in ImplBgfx_RenderDrawData.
class TextureIdBgfx < FFI::Struct
layout :handle, Bgfx_texture_handle_t.by_value,
:flags, :uint8,
:mip, :uint8
end
class TextureIdImGui < FFI::Union
layout :id, :ImTextureID,
:id, TextureIdBgfx.by_value
end
@@m_layout = Bgfx_vertex_layout_t.new # bgfx::VertexLayout
@@m_program = nil # bgfx::ProgramHandle
@@m_imageProgram = nil # bgfx::ProgramHandle
@@m_texture = nil # bgfx::TextureHandle
@@s_tex = nil # bgfx::UniformHandle
@@u_imageLodEnabled = nil # bgfx::UniformHandle
@@m_viewId = 255 # bgfx::ViewId
@@g_BackendRendererName = FFI::MemoryPointer.from_string("imgui_impl_bgfx")
@@font = nil
def self.ImplBgfx_GetFont()
return @@font
end
def self.ImplBgfx_Init()
io = ImGuiIO.new(ImGui::GetIO())
io[:BackendRendererName] = @@g_BackendRendererName
@@m_program = BgfxUtils.load_program("vs_ocornut_imgui", "fs_ocornut_imgui", "./")
@@u_imageLodEnabled = Bgfx::bgfx_create_uniform("u_imageLodEnabled", Bgfx::UniformType::Vec4, -1)
@@m_imageProgram = BgfxUtils.load_program("vs_imgui_image", "fs_imgui_image", "./")
Bgfx::bgfx_vertex_layout_begin(@@m_layout, Bgfx::RendererType::Noop)
Bgfx::bgfx_vertex_layout_add(@@m_layout, Bgfx::Attrib::Position, 2, Bgfx::AttribType::Float, false, false)
Bgfx::bgfx_vertex_layout_add(@@m_layout, Bgfx::Attrib::TexCoord0, 2, Bgfx::AttribType::Float, false, false)
Bgfx::bgfx_vertex_layout_add(@@m_layout, Bgfx::Attrib::Color0, 4, Bgfx::AttribType::Uint8, true, false)
Bgfx::bgfx_vertex_layout_end(@@m_layout)
@@s_tex = Bgfx::bgfx_create_uniform("s_tex", Bgfx::UniformType::Sampler, -1)
io[:Fonts].AddFontDefault()
@@font = io[:Fonts].AddFontFromFileTTF('./jpfont/GenShinGothic-Normal.ttf', 24.0, nil, io[:Fonts].GetGlyphRangesChineseFull())
pixels = FFI::MemoryPointer.new :pointer
width = FFI::MemoryPointer.new :int
height = FFI::MemoryPointer.new :int
io[:Fonts].GetTexDataAsRGBA32(pixels, width, height, nil)
ptr = Bgfx::bgfx_copy(pixels.read_pointer, width.read_uint16 * height.read_uint16 * 4)
mem = Bgfx_memory_t.new(ptr)
@@m_texture = Bgfx::bgfx_create_texture_2d(width.read_uint16, height.read_uint16, false, 1, Bgfx::TextureFormat::BGRA8, 0, mem)
return true
end
def self.ImplBgfx_Shutdown()
Bgfx::bgfx_destroy_uniform(@@s_tex) if @@s_tex != nil
Bgfx::bgfx_destroy_texture(@@m_texture) if @@m_texture != nil
Bgfx::bgfx_destroy_uniform(@@u_imageLodEnabled) if @@u_imageLodEnabled != nil
Bgfx::bgfx_destroy_program(@@m_imageProgram) if @@m_imageProgram != nil
Bgfx::bgfx_destroy_program(@@m_program) if @@m_program != nil
end
def self.ImplBgfx_RenderDrawData(draw_data_raw)
io = ImGuiIO.new(ImGui::GetIO())
window_width = io[:DisplaySize][:x]
window_height = io[:DisplaySize][:y]
Bgfx::bgfx_set_view_name(@@m_viewId, "ImGui")
Bgfx::bgfx_set_view_mode(@@m_viewId, Bgfx::ViewMode::Sequential)
mtxOrtho = RMtx4.new.orthoRH(window_width.to_f, window_height.to_f, 0.0, 1000.0 ) # TODO bgfx::getCaps()->homogeneousDepth
ortho = FFI::MemoryPointer.new(:float, 16).write_array_of_float(mtxOrtho.to_a)
Bgfx::bgfx_set_view_transform(@@m_viewId, nil, ortho)
Bgfx::bgfx_set_view_rect(@@m_viewId, 0, 0, window_width, window_height)
draw_data = ImDrawData.new(draw_data_raw)
# Render command lists
draw_data[:CmdListsCount].times do |n|
tvb = Bgfx_transient_vertex_buffer_t.new
tib = Bgfx_transient_index_buffer_t.new
draw_list = ImDrawList.new((draw_data[:CmdLists].pointer + 8 * n).read_pointer) # 8 == const ImDrawList*
num_vertices = draw_list[:VtxBuffer][:Size]
num_indices = draw_list[:IdxBuffer][:Size]
transient_buffers_available =
(num_vertices == Bgfx::bgfx_get_avail_transient_vertex_buffer(num_vertices, @@m_layout)) &&
(0 == num_indices || num_indices == Bgfx::bgfx_get_avail_transient_index_buffer(num_indices)) # == checkAvailTransientBuffers()
break if not transient_buffers_available
Bgfx::bgfx_alloc_transient_vertex_buffer(tvb, num_vertices, @@m_layout)
Bgfx::bgfx_alloc_transient_index_buffer(tib, num_indices)
tvb[:data].write_string(draw_list[:VtxBuffer][:Data].read_bytes(num_vertices * ImDrawVert.size))
tib[:data].write_string(draw_list[:IdxBuffer][:Data].read_bytes(num_indices * 2)) # 2 == ImDrawIdx(== :ushort ).size
offset = 0
draw_list[:CmdBuffer][:Size].times do |i|
cmd = ImDrawCmd.new(draw_list[:CmdBuffer][:Data] + ImDrawCmd.size * i) # const ImDrawCmd*
if cmd[:UserCallback] != nil
# [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
# cmd[:UserCallback](draw_list, cmd)
elsif cmd[:ElemCount] != 0
state = 0 | Bgfx::State_Write_Rgb | Bgfx::State_Write_A | Bgfx::State_Msaa
th = @@m_texture
program = @@m_program
if cmd[:TextureId] != nil
puts "Not implemented yet" # TODO
else
# ↓state |= BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA);
state |= ((Bgfx::State_Blend_SrcAlpha | (Bgfx::State_Blend_InvSrcAlpha << 4)) |
((Bgfx::State_Blend_SrcAlpha | (Bgfx::State_Blend_InvSrcAlpha << 4)) << 8))
end
xx = [cmd[:ClipRect][:x], 0.0].max.to_i
yy = [cmd[:ClipRect][:y], 0.0].max.to_i
Bgfx::bgfx_set_scissor(xx, yy, ([cmd[:ClipRect][:z], 65535.0].min-xx).to_i, ([cmd[:ClipRect][:w], 65535.0].min-yy).to_i)
Bgfx::bgfx_set_state(state, 0)
Bgfx::bgfx_set_texture(0, @@s_tex, th, 0xffffffff) # 0xffffffff == UINT32_MAX
Bgfx::bgfx_set_transient_vertex_buffer(0, tvb, 0, num_vertices)
Bgfx::bgfx_set_transient_index_buffer(tib, offset, cmd[:ElemCount])
Bgfx::bgfx_submit(@@m_viewId, program, 0, Bgfx::Discard_All)
end
offset += cmd[:ElemCount]
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment