import * as ImGui from "imgui-js" ; let clipboard_text = "" ; let canvas = null ; export let gl = null ; let g_ShaderHandle = null ; let g_VertHandle = null ; let g_FragHandle = null ; let g_AttribLocationTex = null ; let g_AttribLocationProjMtx = null ; let g_AttribLocationPosition = - 1 ; let g_AttribLocationUV = - 1 ; let g_AttribLocationColor = - 1 ; let g_VboHandle = null ; let g_ElementsHandle = null ; let g_FontTexture = null ; export let ctx = null ; let prev_time = 0 ; function document_on_copy ( event ) { if ( event . clipboardData ) { event . clipboardData . setData ( "text/plain" , clipboard_text ) ; } event . preventDefault ( ) ; } function document_on_cut ( event ) { if ( event . clipboardData ) { event . clipboardData . setData ( "text/plain" , clipboard_text ) ; } event . preventDefault ( ) ; } function document_on_paste ( event ) { if ( event . clipboardData ) { clipboard_text = event . clipboardData . getData ( "text/plain" ) ; } event . preventDefault ( ) ; } function window_on_resize ( ) { if ( canvas !== null ) { canvas . width = canvas . scrollWidth ; canvas . height = canvas . scrollHeight ; } } function window_on_gamepadconnected ( event ) { console . log ( "Gamepad connected at index %d: %s. %d buttons, %d axes." , event . gamepad . index , event . gamepad . id , event . gamepad . buttons . length , event . gamepad . axes . length ) ; } function window_on_gamepaddisconnected ( event ) { console . log ( "Gamepad disconnected at index %d: %s." , event . gamepad . index , event . gamepad . id ) ; } function canvas_on_blur ( event ) { const io = ImGui . GetIO ( ) ; io . KeyCtrl = false ; io . KeyShift = false ; io . KeyAlt = false ; io . KeySuper = false ; for ( let i = 0 ; i < io . KeysDown . length ; ++ i ) { io . KeysDown [ i ] = false ; } for ( let i = 0 ; i < io . MouseDown . length ; ++ i ) { io . MouseDown [ i ] = false ; } } const key_code_to_index = { "NumpadEnter" : 176 , } ; function canvas_on_keydown ( event ) { const io = ImGui . GetIO ( ) ; io . KeyCtrl = event . ctrlKey ; io . KeyShift = event . shiftKey ; io . KeyAlt = event . altKey ; io . KeySuper = event . metaKey ; const key_index = key_code_to_index [ event . code ] || event . keyCode ; ImGui . ASSERT ( key_index >= 0 && key_index < ImGui . ARRAYSIZE ( io . KeysDown ) ) ; io . KeysDown [ key_index ] = true ; if ( event . key === "Tab" ) { event . preventDefault ( ) ; } } function canvas_on_keyup ( event ) { const io = ImGui . GetIO ( ) ; io . KeyCtrl = event . ctrlKey ; io . KeyShift = event . shiftKey ; io . KeyAlt = event . altKey ; io . KeySuper = event . metaKey ; const key_index = key_code_to_index [ event . code ] || event . keyCode ; ImGui . ASSERT ( key_index >= 0 && key_index < ImGui . ARRAYSIZE ( io . KeysDown ) ) ; io . KeysDown [ key_index ] = false ; if ( io . WantCaptureKeyboard ) { event . preventDefault ( ) ; } } function canvas_on_keypress ( event ) { const io = ImGui . GetIO ( ) ; io . AddInputCharacter ( event . charCode ) ; if ( io . WantCaptureKeyboard ) { event . preventDefault ( ) ; } } function canvas_on_pointermove ( event ) { const io = ImGui . GetIO ( ) ; io . MousePos . x = event . offsetX ; io . MousePos . y = event . offsetY ; if ( io . WantCaptureMouse ) { event . preventDefault ( ) ; } } const mouse_button_map = [ 0 , 2 , 1 , 3 , 4 ] ; function canvas_on_pointerdown ( event ) { const io = ImGui . GetIO ( ) ; io . MousePos . x = event . offsetX ; io . MousePos . y = event . offsetY ; io . MouseDown [ mouse_button_map [ event . button ] ] = true ; } function canvas_on_contextmenu ( event ) { const io = ImGui . GetIO ( ) ; if ( io . WantCaptureMouse ) { event . preventDefault ( ) ; } } function canvas_on_pointerup ( event ) { const io = ImGui . GetIO ( ) ; io . MouseDown [ mouse_button_map [ event . button ] ] = false ; if ( io . WantCaptureMouse ) { event . preventDefault ( ) ; } } function canvas_on_wheel ( event ) { const io = ImGui . GetIO ( ) ; let scale = 1.0 ; switch ( event . deltaMode ) { case event . DOM_DELTA_PIXEL : scale = 0.01 ; break ; case event . DOM_DELTA_LINE : scale = 0.2 ; break ; case event . DOM_DELTA_PAGE : scale = 1.0 ; break ; } io . MouseWheelH = event . deltaX * scale ; io . MouseWheel = - event . deltaY * scale ; if ( io . WantCaptureMouse ) { event . preventDefault ( ) ; } } export function Init ( value ) { const io = ImGui . GetIO ( ) ; if ( typeof ( window ) !== "undefined" ) { io . BackendPlatformName = "imgui_impl_browser" ; ImGui . LoadIniSettingsFromMemory ( window . localStorage . getItem ( "imgui.ini" ) || "" ) ; } else { io . BackendPlatformName = "imgui_impl_console" ; } if ( typeof ( navigator ) !== "undefined" ) { io . ConfigMacOSXBehaviors = navigator . platform . match ( /Mac/ ) !== null ; } if ( typeof ( document ) !== "undefined" ) { document . body . addEventListener ( "copy" , document_on_copy ) ; document . body . addEventListener ( "cut" , document_on_cut ) ; document . body . addEventListener ( "paste" , document_on_paste ) ; } io . SetClipboardTextFn = ( user_data , text ) : void => { clipboard_text = text ; if ( typeof navigator !== "undefined" && typeof ( navigator as any ) . clipboard !== "undefined" ) { ( navigator as any ) . clipboard . writeText ( clipboard_text ) . then ( ( ) : void => { } ) ; } } ; io . GetClipboardTextFn = ( user_data ) : string => { return clipboard_text ; } ; io . ClipboardUserData = null ; if ( typeof ( window ) !== "undefined" ) { window . addEventListener ( "resize" , window_on_resize ) ; window . addEventListener ( "gamepadconnected" , window_on_gamepadconnected ) ; window . addEventListener ( "gamepaddisconnected" , window_on_gamepaddisconnected ) ; } if ( typeof ( window ) !== "undefined" ) { if ( value instanceof ( HTMLCanvasElement ) ) { canvas = value ; value = canvas . getContext ( "webgl2" , { alpha : false } ) || canvas . getContext ( "webgl" , { alpha : false } ) || canvas . getContext ( "2d" ) ; } if ( typeof WebGL2RenderingContext !== "undefined" && value instanceof ( WebGL2RenderingContext ) ) { io . BackendRendererName = "imgui_impl_webgl2" ; canvas = canvas || value . canvas as HTMLCanvasElement ; gl = value ; } else if ( typeof WebGLRenderingContext !== "undefined" && value instanceof ( WebGLRenderingContext ) ) { io . BackendRendererName = "imgui_impl_webgl" ; canvas = canvas || value . canvas as HTMLCanvasElement ; gl = value ; } else if ( typeof CanvasRenderingContext2D !== "undefined" && value instanceof ( CanvasRenderingContext2D ) ) { io . BackendRendererName = "imgui_impl_2d" ; canvas = canvas || value . canvas ; ctx = value ; } } if ( canvas !== null ) { window_on_resize ( ) ; canvas . style . touchAction = "none" ; canvas . addEventListener ( "blur" , canvas_on_blur ) ; canvas . addEventListener ( "keydown" , canvas_on_keydown ) ; canvas . addEventListener ( "keyup" , canvas_on_keyup ) ; canvas . addEventListener ( "keypress" , canvas_on_keypress ) ; canvas . addEventListener ( "pointermove" , canvas_on_pointermove ) ; canvas . addEventListener ( "pointerdown" , canvas_on_pointerdown ) ; canvas . addEventListener ( "contextmenu" , canvas_on_contextmenu ) ; canvas . addEventListener ( "pointerup" , canvas_on_pointerup ) ; canvas . addEventListener ( "wheel" , canvas_on_wheel ) ; } io . BackendFlags |= ImGui . BackendFlags . HasMouseCursors ; io . KeyMap [ ImGui . Key . Tab ] = 9 ; io . KeyMap [ ImGui . Key . LeftArrow ] = 37 ; io . KeyMap [ ImGui . Key . RightArrow ] = 39 ; io . KeyMap [ ImGui . Key . UpArrow ] = 38 ; io . KeyMap [ ImGui . Key . DownArrow ] = 40 ; io . KeyMap [ ImGui . Key . PageUp ] = 33 ; io . KeyMap [ ImGui . Key . PageDown ] = 34 ; io . KeyMap [ ImGui . Key . Home ] = 36 ; io . KeyMap [ ImGui . Key . End ] = 35 ; io . KeyMap [ ImGui . Key . Insert ] = 45 ; io . KeyMap [ ImGui . Key . Delete ] = 46 ; io . KeyMap [ ImGui . Key . Backspace ] = 8 ; io . KeyMap [ ImGui . Key . Space ] = 32 ; io . KeyMap [ ImGui . Key . Enter ] = 13 ; io . KeyMap [ ImGui . Key . Escape ] = 27 ; io . KeyMap [ ImGui . Key . KeyPadEnter ] = key_code_to_index [ "NumpadEnter" ] ; io . KeyMap [ ImGui . Key . A ] = 65 ; io . KeyMap [ ImGui . Key . C ] = 67 ; io . KeyMap [ ImGui . Key . V ] = 86 ; io . KeyMap [ ImGui . Key . X ] = 88 ; io . KeyMap [ ImGui . Key . Y ] = 89 ; io . KeyMap [ ImGui . Key . Z ] = 90 ; CreateDeviceObjects ( ) ; } export function Shutdown ( ) { DestroyDeviceObjects ( ) ; if ( canvas !== null ) { canvas . removeEventListener ( "blur" , canvas_on_blur ) ; canvas . removeEventListener ( "keydown" , canvas_on_keydown ) ; canvas . removeEventListener ( "keyup" , canvas_on_keyup ) ; canvas . removeEventListener ( "keypress" , canvas_on_keypress ) ; canvas . removeEventListener ( "pointermove" , canvas_on_pointermove ) ; canvas . removeEventListener ( "pointerdown" , canvas_on_pointerdown ) ; canvas . removeEventListener ( "contextmenu" , canvas_on_contextmenu ) ; canvas . removeEventListener ( "pointerup" , canvas_on_pointerup ) ; canvas . removeEventListener ( "wheel" , canvas_on_wheel ) ; } gl = null ; ctx = null ; canvas = null ; if ( typeof ( window ) !== "undefined" ) { window . removeEventListener ( "resize" , window_on_resize ) ; window . removeEventListener ( "gamepadconnected" , window_on_gamepadconnected ) ; window . removeEventListener ( "gamepaddisconnected" , window_on_gamepaddisconnected ) ; } if ( typeof ( document ) !== "undefined" ) { document . body . removeEventListener ( "copy" , document_on_copy ) ; document . body . removeEventListener ( "cut" , document_on_cut ) ; document . body . removeEventListener ( "paste" , document_on_paste ) ; } } export function NewFrame ( time ) { const io = ImGui . GetIO ( ) ; if ( io . WantSaveIniSettings ) { io . WantSaveIniSettings = false ; if ( typeof ( window ) !== "undefined" ) { window . localStorage . setItem ( "imgui.ini" , ImGui . SaveIniSettingsToMemory ( ) ) ; } } const w = canvas && canvas . scrollWidth || 640 ; const h = canvas && canvas . scrollHeight || 480 ; const display_w = gl && gl . drawingBufferWidth || w ; const display_h = gl && gl . drawingBufferHeight || h ; io . DisplaySize . x = w ; io . DisplaySize . y = h ; io . DisplayFramebufferScale . x = w > 0 ? ( display_w / w ) : 0 ; io . DisplayFramebufferScale . y = h > 0 ? ( display_h / h ) : 0 ; const dt = time - prev_time ; prev_time = time ; io . DeltaTime = dt / 1000 ; if ( io . WantSetMousePos ) { console . log ( "TODO: MousePos" , io . MousePos . x , io . MousePos . y ) ; } if ( typeof ( document ) !== "undefined" ) { if ( io . MouseDrawCursor ) { document . body . style . cursor = "none" ; } else { switch ( ImGui . GetMouseCursor ( ) ) { case ImGui . MouseCursor . None : document . body . style . cursor = "none" ; break ; default : case ImGui . MouseCursor . Arrow : document . body . style . cursor = "default" ; break ; case ImGui . MouseCursor . TextInput : document . body . style . cursor = "text" ; break ; case ImGui . MouseCursor . ResizeAll : document . body . style . cursor = "all-scroll" ; break ; case ImGui . MouseCursor . ResizeNS : document . body . style . cursor = "ns-resize" ; break ; case ImGui . MouseCursor . ResizeEW : document . body . style . cursor = "ew-resize" ; break ; case ImGui . MouseCursor . ResizeNESW : document . body . style . cursor = "nesw-resize" ; break ; case ImGui . MouseCursor . ResizeNWSE : document . body . style . cursor = "nwse-resize" ; break ; case ImGui . MouseCursor . Hand : document . body . style . cursor = "move" ; break ; case ImGui . MouseCursor . NotAllowed : document . body . style . cursor = "not-allowed" ; break ; } } } for ( let i = 0 ; i < io . NavInputs . length ; ++ i ) { } if ( io . ConfigFlags & ImGui . ConfigFlags . NavEnableGamepad ) { const gamepads = ( typeof ( navigator ) !== "undefined" && typeof ( navigator . getGamepads ) === "function" ) ? navigator . getGamepads ( ) : [ ] ; for ( let i = 0 ; i < gamepads . length ; ++ i ) { const gamepad = gamepads [ i ] ; if ( ! gamepad ) { continue ; } io . BackendFlags |= ImGui . BackendFlags . HasGamepad ; const buttons_count = gamepad . buttons . length ; const axes_count = gamepad . axes . length ; function MAP_BUTTON ( NAV_NO , BUTTON_NO ) { if ( ! gamepad ) { return ; } if ( buttons_count > BUTTON_NO && gamepad . buttons [ BUTTON_NO ] . pressed ) io . NavInputs [ NAV_NO ] = 1.0 ; } function MAP_ANALOG ( NAV_NO , AXIS_NO , V0 , V1 ) { if ( ! gamepad ) { return ; } let v = ( axes_count > AXIS_NO ) ? gamepad . axes [ AXIS_NO ] : V0 ; v = ( v - V0 ) / ( V1 - V0 ) ; if ( v > 1.0 ) v = 1.0 ; if ( io . NavInputs [ NAV_NO ] < v ) io . NavInputs [ NAV_NO ] = v ; } const match = gamepad . id . match ( /^([0-9a-f]{4})-([0-9a-f]{4})-.*$/ ) ; const match_chrome = gamepad . id . match ( /^.*\(.*Vendor: ([0-9a-f]{4}) Product: ([0-9a-f]{4})\).*$/ ) ; const vendor = ( match && match [ 1 ] ) || ( match_chrome && match_chrome [ 1 ] ) || "0000" ; const product = ( match && match [ 2 ] ) || ( match_chrome && match_chrome [ 2 ] ) || "0000" ; switch ( vendor + product ) { case "046dc216" : MAP_BUTTON ( ImGui . NavInput . Activate , 1 ) ; MAP_BUTTON ( ImGui . NavInput . Cancel , 2 ) ; MAP_BUTTON ( ImGui . NavInput . Menu , 0 ) ; MAP_BUTTON ( ImGui . NavInput . Input , 3 ) ; MAP_ANALOG ( ImGui . NavInput . DpadLeft , 4 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . DpadRight , 4 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . DpadUp , 5 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . DpadDown , 5 , + 0.3 , + 0.9 ) ; MAP_BUTTON ( ImGui . NavInput . FocusPrev , 4 ) ; MAP_BUTTON ( ImGui . NavInput . FocusNext , 5 ) ; MAP_BUTTON ( ImGui . NavInput . TweakSlow , 6 ) ; MAP_BUTTON ( ImGui . NavInput . TweakFast , 7 ) ; MAP_ANALOG ( ImGui . NavInput . LStickLeft , 0 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickRight , 0 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickUp , 1 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickDown , 1 , + 0.3 , + 0.9 ) ; break ; case "046dc21d" : MAP_BUTTON ( ImGui . NavInput . Activate , 0 ) ; MAP_BUTTON ( ImGui . NavInput . Cancel , 1 ) ; MAP_BUTTON ( ImGui . NavInput . Menu , 2 ) ; MAP_BUTTON ( ImGui . NavInput . Input , 3 ) ; MAP_BUTTON ( ImGui . NavInput . DpadLeft , 14 ) ; MAP_BUTTON ( ImGui . NavInput . DpadRight , 15 ) ; MAP_BUTTON ( ImGui . NavInput . DpadUp , 12 ) ; MAP_BUTTON ( ImGui . NavInput . DpadDown , 13 ) ; MAP_BUTTON ( ImGui . NavInput . FocusPrev , 4 ) ; MAP_BUTTON ( ImGui . NavInput . FocusNext , 5 ) ; MAP_ANALOG ( ImGui . NavInput . TweakSlow , 6 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . TweakFast , 7 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickLeft , 0 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickRight , 0 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickUp , 1 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickDown , 1 , + 0.3 , + 0.9 ) ; break ; case "2dc86001" : case "2dc86101" : MAP_BUTTON ( ImGui . NavInput . Activate , 1 ) ; MAP_BUTTON ( ImGui . NavInput . Cancel , 0 ) ; MAP_BUTTON ( ImGui . NavInput . Menu , 4 ) ; MAP_BUTTON ( ImGui . NavInput . Input , 3 ) ; MAP_ANALOG ( ImGui . NavInput . DpadLeft , 6 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . DpadRight , 6 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . DpadUp , 7 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . DpadDown , 7 , + 0.3 , + 0.9 ) ; MAP_BUTTON ( ImGui . NavInput . FocusPrev , 6 ) ; MAP_BUTTON ( ImGui . NavInput . FocusNext , 7 ) ; MAP_BUTTON ( ImGui . NavInput . TweakSlow , 8 ) ; MAP_BUTTON ( ImGui . NavInput . TweakFast , 9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickLeft , 0 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickRight , 0 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickUp , 1 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickDown , 1 , + 0.3 , + 0.9 ) ; break ; default : MAP_BUTTON ( ImGui . NavInput . Activate , 0 ) ; MAP_BUTTON ( ImGui . NavInput . Cancel , 1 ) ; MAP_BUTTON ( ImGui . NavInput . Menu , 2 ) ; MAP_BUTTON ( ImGui . NavInput . Input , 3 ) ; MAP_BUTTON ( ImGui . NavInput . DpadLeft , 14 ) ; MAP_BUTTON ( ImGui . NavInput . DpadRight , 15 ) ; MAP_BUTTON ( ImGui . NavInput . DpadUp , 12 ) ; MAP_BUTTON ( ImGui . NavInput . DpadDown , 13 ) ; MAP_BUTTON ( ImGui . NavInput . FocusPrev , 4 ) ; MAP_BUTTON ( ImGui . NavInput . FocusNext , 5 ) ; MAP_BUTTON ( ImGui . NavInput . TweakSlow , 6 ) ; MAP_BUTTON ( ImGui . NavInput . TweakFast , 7 ) ; MAP_ANALOG ( ImGui . NavInput . LStickLeft , 0 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickRight , 0 , + 0.3 , + 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickUp , 1 , - 0.3 , - 0.9 ) ; MAP_ANALOG ( ImGui . NavInput . LStickDown , 1 , + 0.3 , + 0.9 ) ; break ; } } } } export function RenderDrawData ( draw_data = ImGui . GetDrawData ( ) ) { const io = ImGui . GetIO ( ) ; if ( draw_data === null ) { throw new Error ( ) ; } gl || ctx || console . log ( draw_data ) ; const fb_width = io . DisplaySize . x * io . DisplayFramebufferScale . x ; const fb_height = io . DisplaySize . y * io . DisplayFramebufferScale . y ; if ( fb_width === 0 || fb_height === 0 ) { return ; } draw_data . ScaleClipRects ( io . DisplayFramebufferScale ) ; const gl2 = typeof WebGL2RenderingContext !== "undefined" && gl instanceof WebGL2RenderingContext && gl || null ; const gl_vao = gl && gl . getExtension ( "OES_vertex_array_object" ) || null ; const last_active_texture = gl && gl . getParameter ( gl . ACTIVE_TEXTURE ) || null ; const last_program = gl && gl . getParameter ( gl . CURRENT_PROGRAM ) || null ; const last_texture = gl && gl . getParameter ( gl . TEXTURE_BINDING_2D ) || null ; const last_array_buffer = gl && gl . getParameter ( gl . ARRAY_BUFFER_BINDING ) || null ; const last_element_array_buffer = gl && gl . getParameter ( gl . ELEMENT_ARRAY_BUFFER_BINDING ) || null ; const last_vertex_array_object = gl2 && gl2 . getParameter ( gl2 . VERTEX_ARRAY_BINDING ) || gl && gl_vao && gl . getParameter ( gl_vao . VERTEX_ARRAY_BINDING_OES ) || null ; const last_viewport = gl && gl . getParameter ( gl . VIEWPORT ) || null ; const last_scissor_box = gl && gl . getParameter ( gl . SCISSOR_BOX ) || null ; const last_blend_src_rgb = gl && gl . getParameter ( gl . BLEND_SRC_RGB ) || null ; const last_blend_dst_rgb = gl && gl . getParameter ( gl . BLEND_DST_RGB ) || null ; const last_blend_src_alpha = gl && gl . getParameter ( gl . BLEND_SRC_ALPHA ) || null ; const last_blend_dst_alpha = gl && gl . getParameter ( gl . BLEND_DST_ALPHA ) || null ; const last_blend_equation_rgb = gl && gl . getParameter ( gl . BLEND_EQUATION_RGB ) || null ; const last_blend_equation_alpha = gl && gl . getParameter ( gl . BLEND_EQUATION_ALPHA ) || null ; const last_enable_blend = gl && gl . getParameter ( gl . BLEND ) || null ; const last_enable_cull_face = gl && gl . getParameter ( gl . CULL_FACE ) || null ; const last_enable_depth_test = gl && gl . getParameter ( gl . DEPTH_TEST ) || null ; const last_enable_scissor_test = gl && gl . getParameter ( gl . SCISSOR_TEST ) || null ; const vertex_array_object = gl2 && gl2 . createVertexArray ( ) || gl_vao && gl_vao . createVertexArrayOES ( ) ; gl && gl . enable ( gl . BLEND ) ; gl && gl . blendEquation ( gl . FUNC_ADD ) ; gl && gl . blendFunc ( gl . SRC_ALPHA , gl . ONE_MINUS_SRC_ALPHA ) ; gl && gl . disable ( gl . CULL_FACE ) ; gl && gl . disable ( gl . DEPTH_TEST ) ; gl && gl . enable ( gl . SCISSOR_TEST ) ; gl && gl . viewport ( 0 , 0 , fb_width , fb_height ) ; const L = draw_data . DisplayPos . x ; const R = draw_data . DisplayPos . x + draw_data . DisplaySize . x ; const T = draw_data . DisplayPos . y ; const B = draw_data . DisplayPos . y + draw_data . DisplaySize . y ; const ortho_projection = new Float32Array ( [ 2.0 / ( R - L ) , 0.0 , 0.0 , 0.0 , 0.0 , 2.0 / ( T - B ) , 0.0 , 0.0 , 0.0 , 0.0 , - 1.0 , 0.0 , ( R + L ) / ( L - R ) , ( T + B ) / ( B - T ) , 0.0 , 1.0 , ] ) ; gl && gl . useProgram ( g_ShaderHandle ) ; gl && gl . uniform1i ( g_AttribLocationTex , 0 ) ; gl && g_AttribLocationProjMtx && gl . uniformMatrix4fv ( g_AttribLocationProjMtx , false , ortho_projection ) ; gl2 && gl2 . bindVertexArray ( vertex_array_object ) || gl_vao && gl_vao . bindVertexArrayOES ( vertex_array_object ) ; gl && gl . bindBuffer ( gl . ARRAY_BUFFER , g_VboHandle ) ; gl && gl . enableVertexAttribArray ( g_AttribLocationPosition ) ; gl && gl . enableVertexAttribArray ( g_AttribLocationUV ) ; gl && gl . enableVertexAttribArray ( g_AttribLocationColor ) ; gl && gl . vertexAttribPointer ( g_AttribLocationPosition , 2 , gl . FLOAT , false , ImGui . DrawVertSize , ImGui . DrawVertPosOffset ) ; gl && gl . vertexAttribPointer ( g_AttribLocationUV , 2 , gl . FLOAT , false , ImGui . DrawVertSize , ImGui . DrawVertUVOffset ) ; gl && gl . vertexAttribPointer ( g_AttribLocationColor , 4 , gl . UNSIGNED_BYTE , true , ImGui . DrawVertSize , ImGui . DrawVertColOffset ) ; const pos = draw_data . DisplayPos ; const idx_buffer_type = gl && ( ( ImGui . DrawIdxSize === 4 ) ? gl . UNSIGNED_INT : gl . UNSIGNED_SHORT ) || 0 ; draw_data . IterateDrawLists ( ( draw_list ) : void => { gl || ctx || console . log ( draw_list ) ; gl || ctx || console . log ( "VtxBuffer.length" , draw_list . VtxBuffer . length ) ; gl || ctx || console . log ( "IdxBuffer.length" , draw_list . IdxBuffer . length ) ; gl && gl . bindBuffer ( gl . ARRAY_BUFFER , g_VboHandle ) ; gl && gl . bufferData ( gl . ARRAY_BUFFER , draw_list . VtxBuffer , gl . STREAM_DRAW ) ; gl && gl . bindBuffer ( gl . ELEMENT_ARRAY_BUFFER , g_ElementsHandle ) ; gl && gl . bufferData ( gl . ELEMENT_ARRAY_BUFFER , draw_list . IdxBuffer , gl . STREAM_DRAW ) ; draw_list . IterateDrawCmds ( ( draw_cmd ) : void => { gl || ctx || console . log ( draw_cmd ) ; gl || ctx || console . log ( "ElemCount" , draw_cmd . ElemCount ) ; gl || ctx || console . log ( "ClipRect" , draw_cmd . ClipRect . x , fb_height - draw_cmd . ClipRect . w , draw_cmd . ClipRect . z - draw_cmd . ClipRect . x , draw_cmd . ClipRect . w - draw_cmd . ClipRect . y ) ; gl || ctx || console . log ( "TextureId" , draw_cmd . TextureId ) ; if ( ! gl && ! ctx ) { console . log ( "i: pos.x pos.y uv.x uv.y col" ) ; for ( let i = 0 ; i < Math . min ( 3 , draw_cmd . ElemCount ) ; ++ i ) { const view = new ImGui . DrawVert ( draw_list . VtxBuffer . buffer , draw_list . VtxBuffer . byteOffset + i * ImGui . DrawVertSize ) ; console . log ( `${ i }: ${ view . pos [ 0 ] . toFixed ( 2 ) } ${ view . pos [ 1 ] . toFixed ( 2 ) } ${ view . uv [ 0 ] . toFixed ( 5 ) } ${ view . uv [ 1 ] . toFixed ( 5 ) } ${ ( "00000000" + view . col [ 0 ] . toString ( 16 ) ) . substr ( - 8 ) }` ) ; } } if ( draw_cmd . UserCallback !== null ) { draw_cmd . UserCallback ( draw_list , draw_cmd ) ; } else { const clip_rect = new ImGui . Vec4 ( draw_cmd . ClipRect . x - pos . x , draw_cmd . ClipRect . y - pos . y , draw_cmd . ClipRect . z - pos . x , draw_cmd . ClipRect . w - pos . y ) ; if ( clip_rect . x < fb_width && clip_rect . y < fb_height && clip_rect . z >= 0.0 && clip_rect . w >= 0.0 ) { gl && gl . scissor ( clip_rect . x , fb_height - clip_rect . w , clip_rect . z - clip_rect . x , clip_rect . w - clip_rect . y ) ; gl && gl . activeTexture ( gl . TEXTURE0 ) ; gl && gl . bindTexture ( gl . TEXTURE_2D , draw_cmd . TextureId ) ; gl && gl . drawElements ( gl . TRIANGLES , draw_cmd . ElemCount , idx_buffer_type , draw_cmd . IdxOffset * ImGui . DrawIdxSize ) ; if ( ctx ) { ctx . save ( ) ; ctx . beginPath ( ) ; ctx . rect ( clip_rect . x , clip_rect . y , clip_rect . z - clip_rect . x , clip_rect . w - clip_rect . y ) ; ctx . clip ( ) ; const idx = ImGui . DrawIdxSize === 4 ? new Uint32Array ( draw_list . IdxBuffer . buffer , draw_list . IdxBuffer . byteOffset + draw_cmd . IdxOffset * ImGui . DrawIdxSize ) : new Uint16Array ( draw_list . IdxBuffer . buffer , draw_list . IdxBuffer . byteOffset + draw_cmd . IdxOffset * ImGui . DrawIdxSize ) ; for ( let i = 0 ; i < draw_cmd . ElemCount ; i += 3 ) { const i0 = idx [ i + 0 ] ; const i1 = idx [ i + 1 ] ; const i2 = idx [ i + 2 ] ; const v0 = new ImGui . DrawVert ( draw_list . VtxBuffer . buffer , draw_list . VtxBuffer . byteOffset + i0 * ImGui . DrawVertSize ) ; const v1 = new ImGui . DrawVert ( draw_list . VtxBuffer . buffer , draw_list . VtxBuffer . byteOffset + i1 * ImGui . DrawVertSize ) ; const v2 = new ImGui . DrawVert ( draw_list . VtxBuffer . buffer , draw_list . VtxBuffer . byteOffset + i2 * ImGui . DrawVertSize ) ; const i3 = idx [ i + 3 ] ; const i4 = idx [ i + 4 ] ; const i5 = idx [ i + 5 ] ; const v3 = new ImGui . DrawVert ( draw_list . VtxBuffer . buffer , draw_list . VtxBuffer . byteOffset + i3 * ImGui . DrawVertSize ) ; const v4 = new ImGui . DrawVert ( draw_list . VtxBuffer . buffer , draw_list . VtxBuffer . byteOffset + i4 * ImGui . DrawVertSize ) ; const v5 = new ImGui . DrawVert ( draw_list . VtxBuffer . buffer , draw_list . VtxBuffer . byteOffset + i5 * ImGui . DrawVertSize ) ; let quad = true ; let minmin = v0 ; let minmax = v0 ; let maxmin = v0 ; let maxmax = v0 ; for ( const v of [ v1 , v2 , v3 , v4 , v5 ] ) { let found = false ; if ( v . pos [ 0 ] <= minmin . pos [ 0 ] && v . pos [ 1 ] <= minmin . pos [ 1 ] ) { minmin = v ; found = true ; } if ( v . pos [ 0 ] <= minmax . pos [ 0 ] && v . pos [ 1 ] >= minmax . pos [ 1 ] ) { minmax = v ; found = true ; } if ( v . pos [ 0 ] >= maxmin . pos [ 0 ] && v . pos [ 1 ] <= maxmin . pos [ 1 ] ) { maxmin = v ; found = true ; } if ( v . pos [ 0 ] >= maxmax . pos [ 0 ] && v . pos [ 1 ] >= maxmax . pos [ 1 ] ) { maxmax = v ; found = true ; } if ( ! found ) { quad = false ; } } quad = quad && ( minmin . pos [ 0 ] === minmax . pos [ 0 ] ) ; quad = quad && ( maxmin . pos [ 0 ] === maxmax . pos [ 0 ] ) ; quad = quad && ( minmin . pos [ 1 ] === maxmin . pos [ 1 ] ) ; quad = quad && ( minmax . pos [ 1 ] === maxmax . pos [ 1 ] ) ; if ( quad ) { if ( minmin . uv [ 0 ] === maxmax . uv [ 0 ] || minmin . uv [ 1 ] === maxmax . uv [ 1 ] ) { ctx . beginPath ( ) ; ctx . rect ( minmin . pos [ 0 ] , minmin . pos [ 1 ] , maxmax . pos [ 0 ] - minmin . pos [ 0 ] , maxmax . pos [ 1 ] - minmin . pos [ 1 ] ) ; ctx . fillStyle = `rgba(${ v0 . col [ 0 ] >> 0 & 0xff }, ${ v0 . col [ 0 ] >> 8 & 0xff }, ${ v0 . col [ 0 ] >> 16 & 0xff }, ${ ( v0 . col [ 0 ] >> 24 & 0xff ) / 0xff })` ; ctx . fill ( ) ; } else { const image = draw_cmd . TextureId as CanvasImageSource ; const width = image instanceof HTMLVideoElement ? image . videoWidth : image . width as number ; const height = image instanceof HTMLVideoElement ? image . videoHeight : image . height as number ; image && ctx . drawImage ( image , minmin . uv [ 0 ] * width , minmin . uv [ 1 ] * height , ( maxmax . uv [ 0 ] - minmin . uv [ 0 ] ) * width , ( maxmax . uv [ 1 ] - minmin . uv [ 1 ] ) * height , minmin . pos [ 0 ] , minmin . pos [ 1 ] , maxmax . pos [ 0 ] - minmin . pos [ 0 ] , maxmax . pos [ 1 ] - minmin . pos [ 1 ] ) ; } i += 3 ; } else { ctx . beginPath ( ) ; ctx . moveTo ( v0 . pos [ 0 ] , v0 . pos [ 1 ] ) ; ctx . lineTo ( v1 . pos [ 0 ] , v1 . pos [ 1 ] ) ; ctx . lineTo ( v2 . pos [ 0 ] , v2 . pos [ 1 ] ) ; ctx . closePath ( ) ; ctx . fillStyle = `rgba(${ v0 . col [ 0 ] >> 0 & 0xff }, ${ v0 . col [ 0 ] >> 8 & 0xff }, ${ v0 . col [ 0 ] >> 16 & 0xff }, ${ ( v0 . col [ 0 ] >> 24 & 0xff ) / 0xff })` ; ctx . fill ( ) ; } } ctx . restore ( ) ; } } } } ) ; } ) ; gl2 && gl2 . deleteVertexArray ( vertex_array_object ) || gl_vao && gl_vao . deleteVertexArrayOES ( vertex_array_object ) ; gl && ( last_program !== null ) && gl . useProgram ( last_program ) ; gl && ( last_texture !== null ) && gl . bindTexture ( gl . TEXTURE_2D , last_texture ) ; gl && ( last_active_texture !== null ) && gl . activeTexture ( last_active_texture ) ; gl2 && gl2 . bindVertexArray ( last_vertex_array_object ) || gl_vao && gl_vao . bindVertexArrayOES ( last_vertex_array_object ) ; gl && ( last_array_buffer !== null ) && gl . bindBuffer ( gl . ARRAY_BUFFER , last_array_buffer ) ; gl && ( last_element_array_buffer !== null ) && gl . bindBuffer ( gl . ELEMENT_ARRAY_BUFFER , last_element_array_buffer ) ; gl && ( last_blend_equation_rgb !== null && last_blend_equation_alpha !== null ) && gl . blendEquationSeparate ( last_blend_equation_rgb , last_blend_equation_alpha ) ; gl && ( last_blend_src_rgb !== null && last_blend_src_alpha !== null && last_blend_dst_rgb !== null && last_blend_dst_alpha !== null ) && gl . blendFuncSeparate ( last_blend_src_rgb , last_blend_src_alpha , last_blend_dst_rgb , last_blend_dst_alpha ) ; gl && ( last_enable_blend ? gl . enable ( gl . BLEND ) : gl . disable ( gl . BLEND ) ) ; gl && ( last_enable_cull_face ? gl . enable ( gl . CULL_FACE ) : gl . disable ( gl . CULL_FACE ) ) ; gl && ( last_enable_depth_test ? gl . enable ( gl . DEPTH_TEST ) : gl . disable ( gl . DEPTH_TEST ) ) ; gl && ( last_enable_scissor_test ? gl . enable ( gl . SCISSOR_TEST ) : gl . disable ( gl . SCISSOR_TEST ) ) ; gl && ( last_viewport !== null ) && gl . viewport ( last_viewport [ 0 ] , last_viewport [ 1 ] , last_viewport [ 2 ] , last_viewport [ 3 ] ) ; gl && ( last_scissor_box !== null ) && gl . scissor ( last_scissor_box [ 0 ] , last_scissor_box [ 1 ] , last_scissor_box [ 2 ] , last_scissor_box [ 3 ] ) ; } export function CreateFontsTexture ( ) { const io = ImGui . GetIO ( ) ; const last_texture = gl && gl . getParameter ( gl . TEXTURE_BINDING_2D ) ; const { width , height , pixels } = io . Fonts . GetTexDataAsRGBA32 ( ) ; g_FontTexture = gl && gl . createTexture ( ) ; gl && gl . bindTexture ( gl . TEXTURE_2D , g_FontTexture ) ; gl && gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MIN_FILTER , gl . LINEAR ) ; gl && gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MAG_FILTER , gl . LINEAR ) ; gl && gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . RGBA , width , height , 0 , gl . RGBA , gl . UNSIGNED_BYTE , pixels ) ; io . Fonts . TexID = g_FontTexture || { foo : "bar" } ; if ( ctx ) { const image_canvas = document . createElement ( "canvas" ) ; image_canvas . width = width ; image_canvas . height = height ; const image_ctx = image_canvas . getContext ( "2d" ) ; if ( image_ctx === null ) { throw new Error ( ) ; } const image_data = image_ctx . getImageData ( 0 , 0 , width , height ) ; image_data . data . set ( pixels ) ; image_ctx . putImageData ( image_data , 0 , 0 ) ; io . Fonts . TexID = image_canvas ; } gl && last_texture && gl . bindTexture ( gl . TEXTURE_2D , last_texture ) ; } export function DestroyFontsTexture ( ) { const io = ImGui . GetIO ( ) ; io . Fonts . TexID = null ; gl && gl . deleteTexture ( g_FontTexture ) ; g_FontTexture = null ; } export function CreateDeviceObjects ( ) { const vertex_shader = [ "uniform mat4 ProjMtx;" , "attribute vec2 Position;" , "attribute vec2 UV;" , "attribute vec4 Color;" , "varying vec2 Frag_UV;" , "varying vec4 Frag_Color;" , "void main() {" , "	Frag_UV = UV;" , "	Frag_Color = Color;" , "	gl_Position = ProjMtx * vec4(Position.xy,0,1);" , "}" , ] ; const fragment_shader = [ "precision mediump float;" , "uniform sampler2D Texture;" , "varying vec2 Frag_UV;" , "varying vec4 Frag_Color;" , "void main() {" , "	gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV);" , "}" , ] ; g_ShaderHandle = gl && gl . createProgram ( ) ; g_VertHandle = gl && gl . createShader ( gl . VERTEX_SHADER ) ; g_FragHandle = gl && gl . createShader ( gl . FRAGMENT_SHADER ) ; gl && gl . shaderSource ( g_VertHandle as WebGLShader , vertex_shader . join ( "\n" ) ) ; gl && gl . shaderSource ( g_FragHandle as WebGLShader , fragment_shader . join ( "\n" ) ) ; gl && gl . compileShader ( g_VertHandle as WebGLShader ) ; gl && gl . compileShader ( g_FragHandle as WebGLShader ) ; gl && gl . attachShader ( g_ShaderHandle as WebGLProgram , g_VertHandle as WebGLShader ) ; gl && gl . attachShader ( g_ShaderHandle as WebGLProgram , g_FragHandle as WebGLShader ) ; gl && gl . linkProgram ( g_ShaderHandle as WebGLProgram ) ; g_AttribLocationTex = gl && gl . getUniformLocation ( g_ShaderHandle as WebGLProgram , "Texture" ) ; g_AttribLocationProjMtx = gl && gl . getUniformLocation ( g_ShaderHandle as WebGLProgram , "ProjMtx" ) ; g_AttribLocationPosition = gl && gl . getAttribLocation ( g_ShaderHandle as WebGLProgram , "Position" ) || 0 ; g_AttribLocationUV = gl && gl . getAttribLocation ( g_ShaderHandle as WebGLProgram , "UV" ) || 0 ; g_AttribLocationColor = gl && gl . getAttribLocation ( g_ShaderHandle as WebGLProgram , "Color" ) || 0 ; g_VboHandle = gl && gl . createBuffer ( ) ; g_ElementsHandle = gl && gl . createBuffer ( ) ; CreateFontsTexture ( ) ; } export function DestroyDeviceObjects ( ) { DestroyFontsTexture ( ) ; gl && gl . deleteBuffer ( g_VboHandle ) ; g_VboHandle = null ; gl && gl . deleteBuffer ( g_ElementsHandle ) ; g_ElementsHandle = null ; g_AttribLocationTex = null ; g_AttribLocationProjMtx = null ; g_AttribLocationPosition = - 1 ; g_AttribLocationUV = - 1 ; g_AttribLocationColor = - 1 ; gl && gl . deleteProgram ( g_ShaderHandle ) ; g_ShaderHandle = null ; gl && gl . deleteShader ( g_VertHandle ) ; g_VertHandle = null ; gl && gl . deleteShader ( g_FragHandle ) ; g_FragHandle = null ; }