2015-01-16 22:41:37 -08:00
/*
* Copyright 2014 - 2015 Daniel Collin . All rights reserved .
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
# include <bgfx.h>
2015-04-15 20:00:15 -07:00
# include <bx/allocator.h>
2015-01-16 22:41:37 -08:00
# include <bx/fpumath.h>
# include <ocornut-imgui/imgui.h>
2015-01-19 17:16:59 -08:00
# include "imgui.h"
2015-01-16 22:41:37 -08:00
# include "ocornut_imgui.h"
# include <stb/stb_image.c>
2015-06-10 09:53:09 -07:00
# if defined(SCI_NAMESPACE)
# include ".. / entry / input.h"
# endif // defined(SCI_NAMESPACE)
2015-01-16 22:41:37 -08:00
# include "vs_ocornut_imgui.bin.h"
# include "fs_ocornut_imgui.bin.h"
2015-01-19 17:16:59 -08:00
struct OcornutImguiContext
2015-01-16 22:41:37 -08:00
{
2015-04-15 20:00:15 -07:00
static void * memAlloc ( size_t _size ) ;
static void memFree ( void * _ptr ) ;
static void renderDrawLists ( ImDrawList * * const _lists , int _count ) ;
2015-01-19 17:16:59 -08:00
void render ( ImDrawList * * const _lists , int _count )
{
const float width = ImGui : : GetIO ( ) . DisplaySize . x ;
const float height = ImGui : : GetIO ( ) . DisplaySize . y ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
float ortho [ 16 ] ;
bx : : mtxOrtho ( ortho , 0.0f , width , height , 0.0f , - 1.0f , 1.0f ) ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
bgfx : : setViewTransform ( m_viewId , NULL , ortho ) ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
// Render command lists
2015-01-19 20:34:54 -08:00
for ( int32_t ii = 0 ; ii < _count ; + + ii )
{
2015-01-19 17:16:59 -08:00
bgfx : : TransientVertexBuffer tvb ;
2015-01-16 22:41:37 -08:00
2015-01-19 20:34:54 -08:00
const ImDrawList * cmd_list = _lists [ ii ] ;
2015-01-19 17:16:59 -08:00
const ImDrawVert * vtx_buffer = cmd_list - > vtx_buffer . begin ( ) ;
2015-06-15 13:12:22 -07:00
uint32_t vtx_size = ( uint32_t ) cmd_list - > vtx_buffer . size ( ) ;
2015-01-18 12:58:56 -08:00
2015-01-19 20:34:54 -08:00
if ( ! bgfx : : checkAvailTransientVertexBuffer ( vtx_size , m_decl ) )
{
2015-01-19 17:16:59 -08:00
// not enough space in transient buffer just quit drawing the rest...
break ;
}
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
bgfx : : allocTransientVertexBuffer ( & tvb , vtx_size , m_decl ) ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
ImDrawVert * verts = ( ImDrawVert * ) tvb . data ;
memcpy ( verts , vtx_buffer , vtx_size * sizeof ( ImDrawVert ) ) ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
uint32_t vtx_offset = 0 ;
2015-06-15 13:12:22 -07:00
const ImDrawCmd * pcmd_begin = cmd_list - > commands . begin ( ) ;
const ImDrawCmd * pcmd_end = cmd_list - > commands . end ( ) ;
2015-01-19 20:34:54 -08:00
for ( const ImDrawCmd * pcmd = pcmd_begin ; pcmd ! = pcmd_end ; pcmd + + )
{
2015-06-15 13:12:22 -07:00
if ( pcmd - > user_callback )
{
pcmd - > user_callback ( cmd_list , pcmd ) ;
vtx_offset + = pcmd - > vtx_count ;
continue ;
}
2015-06-02 14:28:22 -07:00
if ( 0 = = pcmd - > vtx_count )
{
continue ;
}
2015-01-19 17:16:59 -08:00
bgfx : : setState ( 0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_BLEND_FUNC ( BGFX_STATE_BLEND_SRC_ALPHA , BGFX_STATE_BLEND_INV_SRC_ALPHA )
2015-01-19 20:34:54 -08:00
| BGFX_STATE_MSAA
) ;
2015-06-09 15:31:53 -06:00
bgfx : : setScissor ( uint16_t ( bx : : fmax ( pcmd - > clip_rect . x , 0.0f ) )
2015-06-15 13:12:22 -07:00
, uint16_t ( bx : : fmax ( pcmd - > clip_rect . y , 0.0f ) )
, uint16_t ( bx : : fmin ( pcmd - > clip_rect . z , 65535.0f ) - bx : : fmax ( pcmd - > clip_rect . x , 0.0f ) )
, uint16_t ( bx : : fmin ( pcmd - > clip_rect . w , 65535.0f ) - bx : : fmax ( pcmd - > clip_rect . y , 0.0f ) )
) ;
union { void * ptr ; bgfx : : TextureHandle handle ; } texture = { pcmd - > texture_id } ;
2015-04-23 17:14:29 -07:00
bgfx : : setTexture ( 0 , s_tex , 0 ! = texture . handle . idx
? texture . handle
: m_texture
) ;
2015-01-19 17:16:59 -08:00
bgfx : : setVertexBuffer ( & tvb , vtx_offset , pcmd - > vtx_count ) ;
bgfx : : setProgram ( m_program ) ;
bgfx : : submit ( m_viewId ) ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
vtx_offset + = pcmd - > vtx_count ;
}
2015-01-16 22:41:37 -08:00
}
}
2015-04-15 20:00:15 -07:00
void create ( const void * _data , uint32_t _size , float _fontSize , bx : : AllocatorI * _allocator )
2015-01-19 17:16:59 -08:00
{
2015-02-21 15:51:03 -08:00
m_viewId = 255 ;
2015-04-15 20:00:15 -07:00
m_allocator = _allocator ;
2015-06-15 13:12:22 -07:00
m_lastScroll = 0 ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2015-04-15 20:00:15 -07:00
io . RenderDrawListsFn = renderDrawLists ;
if ( NULL ! = m_allocator )
{
io . MemAllocFn = memAlloc ;
io . MemFreeFn = memFree ;
}
2015-01-19 17:16:59 -08:00
io . DisplaySize = ImVec2 ( 1280.0f , 720.0f ) ;
io . DeltaTime = 1.0f / 60.0f ;
2015-04-05 09:04:16 +02:00
io . IniFilename = NULL ;
2015-06-03 14:38:00 -07:00
io . PixelCenterOffset = bgfx : : RendererType : : Direct3D9 = = bgfx : : getRendererType ( ) ? 0.0f : 0.5f ;
2015-01-16 22:41:37 -08:00
2015-06-10 09:53:09 -07:00
# if defined(SCI_NAMESPACE)
io . KeyMap [ ImGuiKey_Tab ] = ( int ) entry : : Key : : Tab ;
io . KeyMap [ ImGuiKey_LeftArrow ] = ( int ) entry : : Key : : Left ;
io . KeyMap [ ImGuiKey_RightArrow ] = ( int ) entry : : Key : : Right ;
io . KeyMap [ ImGuiKey_UpArrow ] = ( int ) entry : : Key : : Up ;
io . KeyMap [ ImGuiKey_DownArrow ] = ( int ) entry : : Key : : Down ;
io . KeyMap [ ImGuiKey_Home ] = ( int ) entry : : Key : : Home ;
io . KeyMap [ ImGuiKey_End ] = ( int ) entry : : Key : : End ;
io . KeyMap [ ImGuiKey_Delete ] = ( int ) entry : : Key : : Delete ;
io . KeyMap [ ImGuiKey_Backspace ] = ( int ) entry : : Key : : Backspace ;
io . KeyMap [ ImGuiKey_Enter ] = ( int ) entry : : Key : : Return ;
io . KeyMap [ ImGuiKey_Escape ] = ( int ) entry : : Key : : Esc ;
io . KeyMap [ ImGuiKey_A ] = ( int ) entry : : Key : : KeyA ;
io . KeyMap [ ImGuiKey_C ] = ( int ) entry : : Key : : KeyC ;
io . KeyMap [ ImGuiKey_V ] = ( int ) entry : : Key : : KeyV ;
io . KeyMap [ ImGuiKey_X ] = ( int ) entry : : Key : : KeyX ;
io . KeyMap [ ImGuiKey_Y ] = ( int ) entry : : Key : : KeyY ;
io . KeyMap [ ImGuiKey_Z ] = ( int ) entry : : Key : : KeyZ ;
# endif // defined(SCI_NAMESPACE)
2015-06-02 14:28:22 -07:00
2015-01-19 17:16:59 -08:00
const bgfx : : Memory * vsmem ;
const bgfx : : Memory * fsmem ;
2015-01-16 22:41:37 -08:00
2015-01-19 20:34:54 -08:00
switch ( bgfx : : getRendererType ( ) )
{
2015-01-19 17:16:59 -08:00
case bgfx : : RendererType : : Direct3D9 :
vsmem = bgfx : : makeRef ( vs_ocornut_imgui_dx9 , sizeof ( vs_ocornut_imgui_dx9 ) ) ;
fsmem = bgfx : : makeRef ( fs_ocornut_imgui_dx9 , sizeof ( fs_ocornut_imgui_dx9 ) ) ;
break ;
case bgfx : : RendererType : : Direct3D11 :
2015-02-16 21:58:13 -08:00
case bgfx : : RendererType : : Direct3D12 :
2015-01-19 17:16:59 -08:00
vsmem = bgfx : : makeRef ( vs_ocornut_imgui_dx11 , sizeof ( vs_ocornut_imgui_dx11 ) ) ;
fsmem = bgfx : : makeRef ( fs_ocornut_imgui_dx11 , sizeof ( fs_ocornut_imgui_dx11 ) ) ;
break ;
default :
vsmem = bgfx : : makeRef ( vs_ocornut_imgui_glsl , sizeof ( vs_ocornut_imgui_glsl ) ) ;
fsmem = bgfx : : makeRef ( fs_ocornut_imgui_glsl , sizeof ( fs_ocornut_imgui_glsl ) ) ;
break ;
}
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
bgfx : : ShaderHandle vsh = bgfx : : createShader ( vsmem ) ;
bgfx : : ShaderHandle fsh = bgfx : : createShader ( fsmem ) ;
m_program = bgfx : : createProgram ( vsh , fsh , true ) ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
m_decl
. begin ( )
. add ( bgfx : : Attrib : : Position , 2 , bgfx : : AttribType : : Float )
. add ( bgfx : : Attrib : : TexCoord0 , 2 , bgfx : : AttribType : : Float )
. add ( bgfx : : Attrib : : Color0 , 4 , bgfx : : AttribType : : Uint8 , true )
. end ( ) ;
2015-01-16 22:41:37 -08:00
2015-05-28 15:27:00 -07:00
s_tex = bgfx : : createUniform ( " s_tex " , bgfx : : UniformType : : Int1 ) ;
2015-01-16 22:41:37 -08:00
2015-01-22 21:01:09 -08:00
uint8_t * data ;
int32_t width ;
int32_t height ;
2015-01-31 22:28:51 -08:00
void * font = ImGui : : MemAlloc ( _size ) ;
2015-01-22 21:01:09 -08:00
memcpy ( font , _data , _size ) ;
2015-01-31 22:28:51 -08:00
io . Fonts - > AddFontFromMemoryTTF ( font , _size , _fontSize ) ;
2015-01-16 22:41:37 -08:00
2015-01-22 21:01:09 -08:00
io . Fonts - > GetTexDataAsRGBA32 ( & data , & width , & height ) ;
2015-01-16 22:41:37 -08:00
2015-06-15 13:12:22 -07:00
m_texture = bgfx : : createTexture2D ( ( uint16_t ) width
2015-01-22 21:01:09 -08:00
, ( uint16_t ) height
2015-01-19 17:16:59 -08:00
, 1
, bgfx : : TextureFormat : : BGRA8
, BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT
2015-01-22 21:01:09 -08:00
, bgfx : : copy ( data , width * height * 4 )
2015-01-19 17:16:59 -08:00
) ;
2015-01-16 22:41:37 -08:00
2015-01-31 19:08:13 -08:00
ImGuiStyle & style = ImGui : : GetStyle ( ) ;
style . FrameRounding = 4.0f ;
2015-01-19 17:16:59 -08:00
}
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
void destroy ( )
{
2015-04-15 20:00:15 -07:00
ImGui : : Shutdown ( ) ;
2015-01-19 17:16:59 -08:00
bgfx : : destroyUniform ( s_tex ) ;
bgfx : : destroyTexture ( m_texture ) ;
bgfx : : destroyProgram ( m_program ) ;
2015-04-15 20:00:15 -07:00
m_allocator = NULL ;
2015-01-19 17:16:59 -08:00
}
2015-01-16 22:41:37 -08:00
2015-06-10 08:53:50 -06:00
void beginFrame ( int32_t _mx , int32_t _my , uint8_t _button , int32_t _scroll , int _width , int _height , char _inputChar , uint8_t _viewId )
2015-01-19 17:16:59 -08:00
{
m_viewId = _viewId ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
2015-06-15 13:12:22 -07:00
if ( _inputChar < 0x7f )
2015-06-10 09:53:09 -07:00
{
2015-06-15 13:12:22 -07:00
io . AddInputCharacter ( _inputChar ) ; // ASCII or GTFO! :(
2015-06-10 09:53:09 -07:00
}
2015-01-19 17:16:59 -08:00
io . DisplaySize = ImVec2 ( ( float ) _width , ( float ) _height ) ;
io . DeltaTime = 1.0f / 60.0f ;
io . MousePos = ImVec2 ( ( float ) _mx , ( float ) _my ) ;
io . MouseDown [ 0 ] = 0 ! = ( _button & IMGUI_MBUT_LEFT ) ;
2015-06-10 09:53:09 -07:00
io . MouseDown [ 1 ] = 0 ! = ( _button & IMGUI_MBUT_RIGHT ) ;
io . MouseWheel = ( float ) ( _scroll - m_lastScroll ) ;
m_lastScroll = _scroll ;
# if defined(SCI_NAMESPACE)
uint8_t modifiers = inputGetModifiersState ( ) ;
io . KeyShift = 0 ! = ( modifiers & ( entry : : Modifier : : LeftShift | entry : : Modifier : : RightShift ) ) ;
io . KeyCtrl = 0 ! = ( modifiers & ( entry : : Modifier : : LeftCtrl | entry : : Modifier : : RightCtrl ) ) ;
io . KeyAlt = 0 ! = ( modifiers & ( entry : : Modifier : : LeftAlt | entry : : Modifier : : RightAlt ) ) ;
for ( int32_t ii = 0 ; ii < ( int32_t ) entry : : Key : : Count ; + + ii )
{
io . KeysDown [ ii ] = inputGetKeyState ( entry : : Key : : Enum ( ii ) ) ;
}
# endif // defined(SCI_NAMESPACE)
2015-06-02 14:28:22 -07:00
2015-01-19 17:16:59 -08:00
ImGui : : NewFrame ( ) ;
2015-01-31 19:08:13 -08:00
2015-03-12 20:34:19 +01:00
//ImGui::ShowTestWindow(); //Debug only.
2015-01-19 17:16:59 -08:00
}
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
void endFrame ( )
{
ImGui : : Render ( ) ;
}
2015-04-15 20:00:15 -07:00
bx : : AllocatorI * m_allocator ;
2015-01-19 17:16:59 -08:00
bgfx : : VertexDecl m_decl ;
bgfx : : ProgramHandle m_program ;
bgfx : : TextureHandle m_texture ;
bgfx : : UniformHandle s_tex ;
uint8_t m_viewId ;
2015-06-15 13:12:22 -07:00
int32_t m_lastScroll ;
2015-01-19 17:16:59 -08:00
} ;
static OcornutImguiContext s_ctx ;
2015-01-16 22:41:37 -08:00
2015-04-15 20:00:15 -07:00
void * OcornutImguiContext : : memAlloc ( size_t _size )
{
return BX_ALLOC ( s_ctx . m_allocator , _size ) ;
}
void OcornutImguiContext : : memFree ( void * _ptr )
{
BX_FREE ( s_ctx . m_allocator , _ptr ) ;
}
void OcornutImguiContext : : renderDrawLists ( ImDrawList * * const _lists , int _count )
2015-01-16 22:41:37 -08:00
{
2015-01-19 17:16:59 -08:00
s_ctx . render ( _lists , _count ) ;
2015-01-16 22:41:37 -08:00
}
2015-04-15 20:00:15 -07:00
void IMGUI_create ( const void * _data , uint32_t _size , float _fontSize , bx : : AllocatorI * _allocator )
2015-01-16 22:41:37 -08:00
{
2015-04-15 20:00:15 -07:00
s_ctx . create ( _data , _size , _fontSize , _allocator ) ;
2015-01-16 22:41:37 -08:00
}
2015-01-19 17:16:59 -08:00
void IMGUI_destroy ( )
2015-01-16 22:41:37 -08:00
{
2015-01-19 17:16:59 -08:00
s_ctx . destroy ( ) ;
2015-01-16 22:41:37 -08:00
}
2015-06-10 08:53:50 -06:00
void IMGUI_beginFrame ( int32_t _mx , int32_t _my , uint8_t _button , int32_t _scroll , int _width , int _height , char _inputChar , uint8_t _viewId )
2015-01-16 22:41:37 -08:00
{
2015-06-10 08:53:50 -06:00
s_ctx . beginFrame ( _mx , _my , _button , _scroll , _width , _height , _inputChar , _viewId ) ;
2015-01-16 22:41:37 -08:00
}
2015-01-19 17:16:59 -08:00
void IMGUI_endFrame ( )
2015-01-16 22:41:37 -08:00
{
2015-01-19 17:16:59 -08:00
s_ctx . endFrame ( ) ;
2015-01-16 22:41:37 -08:00
}