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>
# 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>
# include "vs_ocornut_imgui.bin.h"
# include "fs_ocornut_imgui.bin.h"
2015-01-19 17:16:59 -08:00
static void imguiRender ( ImDrawList * * const _lists , int cmd_lists_count ) ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
struct OcornutImguiContext
2015-01-16 22:41:37 -08:00
{
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 17:16:59 -08:00
uint32_t vtx_size = 0 ;
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-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
const ImDrawCmd * pcmd_begin = cmd_list - > commands . begin ( ) ;
2015-01-19 20:34:54 -08:00
const ImDrawCmd * pcmd_end = cmd_list - > commands . end ( ) ;
for ( const ImDrawCmd * pcmd = pcmd_begin ; pcmd ! = pcmd_end ; pcmd + + )
{
2015-01-19 17:16:59 -08:00
vtx_size + = ( uint32_t ) pcmd - > vtx_count ;
}
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-01-19 20:34:54 -08:00
for ( const ImDrawCmd * pcmd = pcmd_begin ; pcmd ! = pcmd_end ; pcmd + + )
{
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-01-19 23:35:49 -08:00
bgfx : : setScissor ( uint16_t ( pcmd - > clip_rect . x )
, uint16_t ( pcmd - > clip_rect . y )
, uint16_t ( pcmd - > clip_rect . z - pcmd - > clip_rect . x )
, uint16_t ( pcmd - > clip_rect . w - pcmd - > clip_rect . y )
2015-01-19 20:34:54 -08:00
) ;
2015-01-19 17:16:59 -08:00
bgfx : : setTexture ( 0 , s_tex , m_texture ) ;
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-01-22 21:01:09 -08:00
void create ( const void * _data , uint32_t _size , float _fontSize )
2015-01-19 17:16:59 -08:00
{
2015-02-21 15:51:03 -08:00
m_viewId = 255 ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . DisplaySize = ImVec2 ( 1280.0f , 720.0f ) ;
io . DeltaTime = 1.0f / 60.0f ;
2015-01-22 21:01:09 -08:00
// io.PixelCenterOffset = bgfx::RendererType::Direct3D9 == bgfx::getRendererType() ? -0.5f : 0.0f;
2015-01-16 22:41:37 -08: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-01-19 17:16:59 -08:00
s_tex = bgfx : : createUniform ( " s_tex " , bgfx : : UniformType : : Uniform1i ) ;
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-01-22 21:01:09 -08:00
m_texture = bgfx : : createTexture2D ( ( uint16_t ) width
, ( 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
io . RenderDrawListsFn = imguiRender ;
}
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
void destroy ( )
{
bgfx : : destroyUniform ( s_tex ) ;
bgfx : : destroyTexture ( m_texture ) ;
bgfx : : destroyProgram ( m_program ) ;
}
2015-01-16 22:41:37 -08:00
2015-01-19 22:15:50 -08:00
void beginFrame ( int32_t _mx , int32_t _my , uint8_t _button , 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-01-19 22:15:50 -08:00
io . AddInputCharacter ( _inputChar & 0x7f ) ; // ASCII or GTFO! :)
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 ) ;
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 ( ) ;
}
bgfx : : VertexDecl m_decl ;
bgfx : : ProgramHandle m_program ;
bgfx : : TextureHandle m_texture ;
bgfx : : UniformHandle s_tex ;
uint8_t m_viewId ;
} ;
static OcornutImguiContext s_ctx ;
2015-01-16 22:41:37 -08:00
2015-01-19 17:16:59 -08:00
static void imguiRender ( 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-01-22 21:01:09 -08:00
void IMGUI_create ( const void * _data , uint32_t _size , float _fontSize )
2015-01-16 22:41:37 -08:00
{
2015-01-22 21:01:09 -08:00
s_ctx . create ( _data , _size , _fontSize ) ;
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-01-19 22:15:50 -08:00
void IMGUI_beginFrame ( int32_t _mx , int32_t _my , uint8_t _button , int _width , int _height , char _inputChar , uint8_t _viewId )
2015-01-16 22:41:37 -08:00
{
2015-01-19 22:15:50 -08:00
s_ctx . beginFrame ( _mx , _my , _button , _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
}