import * as ImGui from "imgui-js" ; import * as ImGui_Impl from "./imgui_impl.js" ; import { ShowDemoWindow } from "./imgui_demo.js" ; import { MemoryEditor } from "./imgui_memory_editor.js" ; let font = null ; let show_demo_window = true ; let show_another_window = false ; const clear_color = new ImGui . Vec4 ( 0.45 , 0.55 , 0.60 , 1.00 ) ; const memory_editor = new MemoryEditor ( ) ; memory_editor . Open = false ; let show_sandbox_window = false ; let show_gamepad_window = false ; let show_movie_window = false ; let f = 0.0 ; let counter = 0 ; let done = false ; async function LoadArrayBuffer ( url ) { const response = await fetch ( url ) ; return response . arrayBuffer ( ) ; } export default async function main ( ) { await ImGui . default ( ) ; if ( typeof ( window ) !== "undefined" ) { window . requestAnimationFrame ( _init ) ; } else { async function _main ( ) { await _init ( ) ; for ( let i = 0 ; i < 3 ; ++ i ) { _loop ( 1 / 60 ) ; } await _done ( ) ; } _main ( ) . catch ( console . error ) ; } } async function AddFontFromFileTTF ( url , size_pixels , font_cfg = null , glyph_ranges = null ) { font_cfg = font_cfg || new ImGui . FontConfig ( ) ; font_cfg . Name = font_cfg . Name || `${ url . split ( /[\\\/]/ ) . pop ( ) }, ${ size_pixels . toFixed ( 0 ) }px` ; return ImGui . GetIO ( ) . Fonts . AddFontFromMemoryTTF ( await LoadArrayBuffer ( url ) , size_pixels , font_cfg , glyph_ranges ) ; } async function _init ( ) { const EMSCRIPTEN_VERSION = `${ ImGui . bind . __EMSCRIPTEN_major__ }.${ ImGui . bind . __EMSCRIPTEN_minor__ }.${ ImGui . bind . __EMSCRIPTEN_tiny__ }` ; console . log ( "Emscripten Version" , EMSCRIPTEN_VERSION ) ; console . log ( "Total allocated space (uordblks) @ _init:" , ImGui . bind . mallinfo ( ) . uordblks ) ; ImGui . CHECKVERSION ( ) ; ImGui . CreateContext ( ) ; const io = ImGui . GetIO ( ) ; ImGui . StyleColorsDark ( ) ; io . Fonts . AddFontDefault ( ) ; font = await AddFontFromFileTTF ( "../imgui/misc/fonts/Roboto-Medium.ttf" , 16.0 ) ; ImGui . ASSERT ( font !== null ) ; if ( typeof ( window ) !== "undefined" ) { const output = document . getElementById ( "output" ) || document . body ; const canvas = document . createElement ( "canvas" ) ; output . appendChild ( canvas ) ; canvas . tabIndex = 1 ; canvas . style . position = "absolute" ; canvas . style . left = "0px" ; canvas . style . right = "0px" ; canvas . style . top = "0px" ; canvas . style . bottom = "0px" ; canvas . style . width = "100%" ; canvas . style . height = "100%" ; canvas . style . userSelect = "none" ; ImGui_Impl . Init ( canvas ) ; } else { ImGui_Impl . Init ( null ) ; } StartUpImage ( ) ; StartUpVideo ( ) ; if ( typeof ( window ) !== "undefined" ) { window . requestAnimationFrame ( _loop ) ; } } function _loop ( time ) { ImGui_Impl . NewFrame ( time ) ; ImGui . NewFrame ( ) ; if ( ! done && show_demo_window ) { done = ShowDemoWindow ( ( value = show_demo_window ) => show_demo_window = value ) ; } { ImGui . Begin ( "Hello, world!" ) ; ImGui . Text ( "This is some useful text." ) ; ImGui . Checkbox ( "Demo Window" , ( value = show_demo_window ) => show_demo_window = value ) ; ImGui . Checkbox ( "Another Window" , ( value = show_another_window ) => show_another_window = value ) ; ImGui . SliderFloat ( "float" , ( value = f ) => f = value , 0.0 , 1.0 ) ; ImGui . ColorEdit3 ( "clear color" , clear_color ) ; if ( ImGui . Button ( "Button" ) ) counter ++ ; ImGui . SameLine ( ) ; ImGui . Text ( `counter = ${ counter }` ) ; ImGui . Text ( `Application average ${ ( 1000.0 / ImGui . GetIO ( ) . Framerate ) . toFixed ( 3 ) } ms/frame (${ ImGui . GetIO ( ) . Framerate . toFixed ( 1 ) } FPS)` ) ; ImGui . Checkbox ( "Memory Editor" , ( value = memory_editor . Open ) => memory_editor . Open = value ) ; if ( memory_editor . Open ) memory_editor . DrawWindow ( "Memory Editor" , ImGui . bind . HEAP8 . buffer ) ; const mi = ImGui . bind . mallinfo ( ) ; ImGui . Text ( `Max. total allocated space (usmblks):  ${ mi . usmblks }` ) ; ImGui . Text ( `Total allocated space (uordblks):      ${ mi . uordblks }` ) ; ImGui . Text ( `Total free space (fordblks):           ${ mi . fordblks }` ) ; if ( ImGui . ImageButton ( image_gl_texture , new ImGui . Vec2 ( 48 , 48 ) ) ) { image_url = image_urls [ ( image_urls . indexOf ( image_url ) + 1 ) % image_urls . length ] ; if ( image_element ) { image_element . src = image_url ; } } if ( ImGui . IsItemHovered ( ) ) { ImGui . BeginTooltip ( ) ; ImGui . Text ( image_url ) ; ImGui . EndTooltip ( ) ; } if ( ImGui . Button ( "Sandbox Window" ) ) { show_sandbox_window = true ; } if ( show_sandbox_window ) ShowSandboxWindow ( "Sandbox Window" , ( value = show_sandbox_window ) => show_sandbox_window = value ) ; ImGui . SameLine ( ) ; if ( ImGui . Button ( "Gamepad Window" ) ) { show_gamepad_window = true ; } if ( show_gamepad_window ) ShowGamepadWindow ( "Gamepad Window" , ( value = show_gamepad_window ) => show_gamepad_window = value ) ; ImGui . SameLine ( ) ; if ( ImGui . Button ( "Movie Window" ) ) { show_movie_window = true ; } if ( show_movie_window ) ShowMovieWindow ( "Movie Window" , ( value = show_movie_window ) => show_movie_window = value ) ; if ( font ) { ImGui . PushFont ( font ) ; ImGui . Text ( `${ font . GetDebugName ( ) }` ) ; if ( font . FindGlyphNoFallback ( 0x5929 ) ) { ImGui . Text ( `U+5929: \u5929` ) ; } ImGui . PopFont ( ) ; } ImGui . End ( ) ; } if ( show_another_window ) { ImGui . Begin ( "Another Window" , ( value = show_another_window ) => show_another_window = value , ImGui . WindowFlags . AlwaysAutoResize ) ; ImGui . Text ( "Hello from another window!" ) ; if ( ImGui . Button ( "Close Me" ) ) show_another_window = false ; ImGui . End ( ) ; } ImGui . EndFrame ( ) ; ImGui . Render ( ) ; const gl = ImGui_Impl . gl ; if ( gl ) { gl . viewport ( 0 , 0 , gl . drawingBufferWidth , gl . drawingBufferHeight ) ; gl . clearColor ( clear_color . x , clear_color . y , clear_color . z , clear_color . w ) ; gl . clear ( gl . COLOR_BUFFER_BIT ) ; } const ctx = ImGui_Impl . ctx ; if ( ctx ) { ctx . fillStyle = `rgba(${ clear_color . x * 0xff }, ${ clear_color . y * 0xff }, ${ clear_color . z * 0xff }, ${ clear_color . w })` ; ctx . fillRect ( 0 , 0 , ctx . canvas . width , ctx . canvas . height ) ; } UpdateVideo ( ) ; ImGui_Impl . RenderDrawData ( ImGui . GetDrawData ( ) ) ; if ( typeof ( window ) !== "undefined" ) { window . requestAnimationFrame ( done ? _done : _loop ) ; } } async function _done ( ) { const gl = ImGui_Impl . gl ; if ( gl ) { gl . viewport ( 0 , 0 , gl . drawingBufferWidth , gl . drawingBufferHeight ) ; gl . clearColor ( clear_color . x , clear_color . y , clear_color . z , clear_color . w ) ; gl . clear ( gl . COLOR_BUFFER_BIT ) ; } const ctx = ImGui_Impl . ctx ; if ( ctx ) { ctx . clearRect ( 0 , 0 , ctx . canvas . width , ctx . canvas . height ) ; } CleanUpImage ( ) ; CleanUpVideo ( ) ; ImGui_Impl . Shutdown ( ) ; ImGui . DestroyContext ( ) ; console . log ( "Total allocated space (uordblks) @ _done:" , ImGui . bind . mallinfo ( ) . uordblks ) ; } function ShowHelpMarker ( desc ) { ImGui . TextDisabled ( "(?)" ) ; if ( ImGui . IsItemHovered ( ) ) { ImGui . BeginTooltip ( ) ; ImGui . PushTextWrapPos ( ImGui . GetFontSize ( ) * 35.0 ) ; ImGui . TextUnformatted ( desc ) ; ImGui . PopTextWrapPos ( ) ; ImGui . EndTooltip ( ) ; } } let source = [ "ImGui.Text(\"Hello, world!\");" , "ImGui.SliderFloat(\"float\"," , "\t(value = f) => f = value," , "\t0.0, 1.0);" , "" , ] . join ( "\n" ) ; function ShowSandboxWindow ( title , p_open = null ) { ImGui . SetNextWindowSize ( new ImGui . Vec2 ( 320 , 240 ) , ImGui . Cond . FirstUseEver ) ; ImGui . Begin ( title , p_open ) ; ImGui . Text ( "Source" ) ; ImGui . SameLine ( ) ; ShowHelpMarker ( "Contents evaluated and appended to the window." ) ; ImGui . PushItemWidth ( - 1 ) ; ImGui . InputTextMultiline ( "##source" , ( _ = source ) => ( source = _ ) , 1024 , ImGui . Vec2 . ZERO , ImGui . InputTextFlags . AllowTabInput ) ; ImGui . PopItemWidth ( ) ; try { eval ( source ) ; } catch ( e ) { ImGui . TextColored ( new ImGui . Vec4 ( 1.0 , 0.0 , 0.0 , 1.0 ) , "error: " ) ; ImGui . SameLine ( ) ; ImGui . Text ( e . message ) ; } ImGui . End ( ) ; } function ShowGamepadWindow ( title , p_open = null ) { ImGui . Begin ( title , p_open , ImGui . WindowFlags . AlwaysAutoResize ) ; const gamepads = ( typeof ( navigator ) !== "undefined" && typeof ( navigator . getGamepads ) === "function" ) ? navigator . getGamepads ( ) : [ ] ; if ( gamepads . length > 0 ) { for ( let i = 0 ; i < gamepads . length ; ++ i ) { const gamepad = gamepads [ i ] ; ImGui . Text ( `gamepad ${ i } ${ gamepad && gamepad . id }` ) ; if ( ! gamepad ) { continue ; } ImGui . Text ( `       ` ) ; for ( let button = 0 ; button < gamepad . buttons . length ; ++ button ) { ImGui . SameLine ( ) ; ImGui . Text ( `${ button . toString ( 16 ) }` ) ; } ImGui . Text ( `buttons` ) ; for ( let button = 0 ; button < gamepad . buttons . length ; ++ button ) { ImGui . SameLine ( ) ; ImGui . Text ( `${ gamepad . buttons [ button ] . value }` ) ; } ImGui . Text ( `axes` ) ; for ( let axis = 0 ; axis < gamepad . axes . length ; ++ axis ) { ImGui . Text ( `${ axis }: ${ gamepad . axes [ axis ] . toFixed ( 2 ) }` ) ; } } } else { ImGui . Text ( "connect a gamepad" ) ; } ImGui . End ( ) ; } const image_urls = [ "https://threejs.org/examples/textures/crate.gif" , "https://threejs.org/examples/textures/sprite.png" , "https://threejs.org/examples/textures/uv_grid_opengl.jpg" , ] ; let image_url = image_urls [ 0 ] ; let image_element = null ; let image_gl_texture = null ; function StartUpImage ( ) { if ( typeof document !== "undefined" ) { image_element = document . createElement ( "img" ) ; image_element . crossOrigin = "anonymous" ; image_element . src = image_url ; } const gl = ImGui_Impl . gl ; if ( gl ) { const width = 256 ; const height = 256 ; const pixels = new Uint8Array ( 4 * width * height ) ; image_gl_texture = gl . createTexture ( ) ; gl . bindTexture ( gl . TEXTURE_2D , image_gl_texture ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MIN_FILTER , gl . LINEAR ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MAG_FILTER , gl . LINEAR ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_S , gl . CLAMP_TO_EDGE ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_T , gl . CLAMP_TO_EDGE ) ; gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . RGBA , width , height , 0 , gl . RGBA , gl . UNSIGNED_BYTE , pixels ) ; if ( image_element ) { image_element . addEventListener ( "load" , ( event ) => { if ( image_element ) { gl . bindTexture ( gl . TEXTURE_2D , image_gl_texture ) ; gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . RGBA , gl . RGBA , gl . UNSIGNED_BYTE , image_element ) ; } } ) ; } } const ctx = ImGui_Impl . ctx ; if ( ctx ) { image_gl_texture = image_element ; } } function CleanUpImage ( ) { const gl = ImGui_Impl . gl ; if ( gl ) { gl . deleteTexture ( image_gl_texture ) ; image_gl_texture = null ; } const ctx = ImGui_Impl . ctx ; if ( ctx ) { image_gl_texture = null ; } image_element = null ; } const video_urls = [ "https://threejs.org/examples/textures/sintel.ogv" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/VolkswagenGTIReview.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4" , "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WhatCarCanYouGetForAGrand.mp4" , ] ; let video_url = video_urls [ 0 ] ; let video_element = null ; let video_gl_texture = null ; let video_w = 640 ; let video_h = 360 ; let video_time_active = false ; let video_time = 0 ; let video_duration = 0 ; function StartUpVideo ( ) { if ( typeof document !== "undefined" ) { video_element = document . createElement ( "video" ) ; video_element . crossOrigin = "anonymous" ; video_element . preload = "auto" ; video_element . src = video_url ; video_element . load ( ) ; } const gl = ImGui_Impl . gl ; if ( gl ) { const width = 256 ; const height = 256 ; const pixels = new Uint8Array ( 4 * width * height ) ; video_gl_texture = gl . createTexture ( ) ; gl . bindTexture ( gl . TEXTURE_2D , video_gl_texture ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MIN_FILTER , gl . LINEAR ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MAG_FILTER , gl . LINEAR ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_S , gl . CLAMP_TO_EDGE ) ; gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_T , gl . CLAMP_TO_EDGE ) ; gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . RGBA , width , height , 0 , gl . RGBA , gl . UNSIGNED_BYTE , pixels ) ; } const ctx = ImGui_Impl . ctx ; if ( ctx ) { video_gl_texture = video_element ; } } function CleanUpVideo ( ) { const gl = ImGui_Impl . gl ; if ( gl ) { gl . deleteTexture ( video_gl_texture ) ; video_gl_texture = null ; } const ctx = ImGui_Impl . ctx ; if ( ctx ) { video_gl_texture = null ; } video_element = null ; } function UpdateVideo ( ) { const gl = ImGui_Impl . gl ; if ( gl && video_element && video_element . readyState >= video_element . HAVE_CURRENT_DATA ) { gl . bindTexture ( gl . TEXTURE_2D , video_gl_texture ) ; gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . RGBA , gl . RGBA , gl . UNSIGNED_BYTE , video_element ) ; } } function ShowMovieWindow ( title , p_open = null ) { ImGui . Begin ( title , p_open , ImGui . WindowFlags . AlwaysAutoResize ) ; if ( video_element !== null ) { if ( p_open && ! p_open ( ) ) { video_element . pause ( ) ; } const w = video_element . videoWidth ; const h = video_element . videoHeight ; if ( w > 0 ) { video_w = w ; } if ( h > 0 ) { video_h = h ; } ImGui . BeginGroup ( ) ; if ( ImGui . BeginCombo ( "##urls" , null , ImGui . ComboFlags . NoPreview | ImGui . ComboFlags . PopupAlignLeft ) ) { for ( let n = 0 ; n < ImGui . ARRAYSIZE ( video_urls ) ; n ++ ) { if ( ImGui . Selectable ( video_urls [ n ] ) ) { video_url = video_urls [ n ] ; console . log ( video_url ) ; video_element . src = video_url ; video_element . autoplay = true ; } } ImGui . EndCombo ( ) ; } ImGui . SameLine ( ) ; ImGui . PushItemWidth ( video_w - 20 ) ; if ( ImGui . InputText ( "##url" , ( value = video_url ) => video_url = value ) ) { console . log ( video_url ) ; video_element . src = video_url ; } ImGui . PopItemWidth ( ) ; ImGui . EndGroup ( ) ; if ( ImGui . ImageButton ( video_gl_texture , new ImGui . Vec2 ( video_w , video_h ) ) ) { if ( video_element . readyState >= video_element . HAVE_CURRENT_DATA ) { video_element . paused ? video_element . play ( ) : video_element . pause ( ) ; } } ImGui . BeginGroup ( ) ; if ( ImGui . Button ( video_element . paused ? "Play" : "Stop" ) ) { if ( video_element . readyState >= video_element . HAVE_CURRENT_DATA ) { video_element . paused ? video_element . play ( ) : video_element . pause ( ) ; } } ImGui . SameLine ( ) ; if ( ! video_time_active ) { video_time = video_element . currentTime ; video_duration = video_element . duration || 0 ; } ImGui . SliderFloat ( "##time" , ( value = video_time ) => video_time = value , 0 , video_duration ) ; const video_time_was_active = video_time_active ; video_time_active = ImGui . IsItemActive ( ) ; if ( ! video_time_active && video_time_was_active ) { video_element . currentTime = video_time ; } ImGui . EndGroup ( ) ; } else { ImGui . Text ( "No Video Element" ) ; } ImGui . End ( ) ; }