// File: Ciaxur[P]yagb-emu/include/imgui/backends/imgui_impl_opengl3.cpp
// Function: ImGui_ImplOpenGL3_CreateDeviceObjects()
bool    ImGui_ImplOpenGL3_CreateDeviceObjects()
{
    // Backup GL state
    GLint last_texture, last_array_buffer;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
    GLint last_vertex_array;
    glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
#endif

    // Parse GLSL version string
    int glsl_version = 130;
    sscanf(g_GlslVersionString, "#version %d", &glsl_version);

    const GLchar* vertex_shader_glsl_120 =
        "uniform mat4 ProjMtx;\n"
        "attribute vec2 Position;\n"
        "attribute vec2 UV;\n"
        "attribute vec4 Color;\n"
        "varying vec2 Frag_UV;\n"
        "varying vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* vertex_shader_glsl_130 =
        "uniform mat4 ProjMtx;\n"
        "in vec2 Position;\n"
        "in vec2 UV;\n"
        "in vec4 Color;\n"
        "out vec2 Frag_UV;\n"
        "out vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* vertex_shader_glsl_300_es =
        "precision mediump float;\n"
        "layout (location = 0) in vec2 Position;\n"
        "layout (location = 1) in vec2 UV;\n"
        "layout (location = 2) in vec4 Color;\n"
        "uniform mat4 ProjMtx;\n"
        "out vec2 Frag_UV;\n"
        "out vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* vertex_shader_glsl_410_core =
        "layout (location = 0) in vec2 Position;\n"
        "layout (location = 1) in vec2 UV;\n"
        "layout (location = 2) in vec4 Color;\n"
        "uniform mat4 ProjMtx;\n"
        "out vec2 Frag_UV;\n"
        "out vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_120 =
        "#ifdef GL_ES\n"
        "    precision mediump float;\n"
        "#endif\n"
        "uniform sampler2D Texture;\n"
        "varying vec2 Frag_UV;\n"
        "varying vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_130 =
        "uniform sampler2D Texture;\n"
        "in vec2 Frag_UV;\n"
        "in vec4 Frag_Color;\n"
        "out vec4 Out_Color;\n"
        "void main()\n"
        "{\n"
        "    Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_300_es =
        "precision mediump float;\n"
        "uniform sampler2D Texture;\n"
        "in vec2 Frag_UV;\n"
        "in vec4 Frag_Color;\n"
        "layout (location = 0) out vec4 Out_Color;\n"
        "void main()\n"
        "{\n"
        "    Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_410_core =
        "in vec2 Frag_UV;\n"
        "in vec4 Frag_Color;\n"
        "uniform sampler2D Texture;\n"
        "layout (location = 0) out vec4 Out_Color;\n"
        "void main()\n"
        "{\n"
        "    Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
        "}\n";

    // Select shaders matching our GLSL versions
    const GLchar* vertex_shader = NULL;
    const GLchar* fragment_shader = NULL;
    if (glsl_version < 130)
    {
        vertex_shader = vertex_shader_glsl_120;
        fragment_shader = fragment_shader_glsl_120;
    }
    else if (glsl_version >= 410)
    {
        vertex_shader = vertex_shader_glsl_410_core;
        fragment_shader = fragment_shader_glsl_410_core;
    }
    else if (glsl_version == 300)
    {
        vertex_shader = vertex_shader_glsl_300_es;
        fragment_shader = fragment_shader_glsl_300_es;
    }
    else
    {
        vertex_shader = vertex_shader_glsl_130;
        fragment_shader = fragment_shader_glsl_130;
    }

    // Create shaders
    const GLchar* vertex_shader_with_version[2] = { g_GlslVersionString, vertex_shader };
    g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL);
    glCompileShader(g_VertHandle);
    CheckShader(g_VertHandle, "vertex shader");

    const GLchar* fragment_shader_with_version[2] = { g_GlslVersionString, fragment_shader };
    g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL);
    glCompileShader(g_FragHandle);
    CheckShader(g_FragHandle, "fragment shader");

    g_ShaderHandle = glCreateProgram();
    glAttachShader(g_ShaderHandle, g_VertHandle);
    glAttachShader(g_ShaderHandle, g_FragHandle);
    glLinkProgram(g_ShaderHandle);
    CheckProgram(g_ShaderHandle, "shader program");

    g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
    g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
    g_AttribLocationVtxPos = (GLuint)glGetAttribLocation(g_ShaderHandle, "Position");
    g_AttribLocationVtxUV = (GLuint)glGetAttribLocation(g_ShaderHandle, "UV");
    g_AttribLocationVtxColor = (GLuint)glGetAttribLocation(g_ShaderHandle, "Color");

    // Create buffers
    glGenBuffers(1, &g_VboHandle);
    glGenBuffers(1, &g_ElementsHandle);

    ImGui_ImplOpenGL3_CreateFontsTexture();

    // Restore modified GL state
    glBindTexture(GL_TEXTURE_2D, last_texture);
    glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
    glBindVertexArray(last_vertex_array);
#endif

    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movl $0x8069, %edi           # imm = 0x8069
leaq -0x4(%rbp), %rsi
callq 0xd800
movl $0x8894, %edi           # imm = 0x8894
leaq -0x8(%rbp), %rsi
callq 0xd800
movl $0x85b5, %edi           # imm = 0x85B5
leaq -0xc(%rbp), %rsi
callq 0xd800
movl $0x82, -0x10(%rbp)
leaq 0xb0a0d(%rip), %rdi     # 0x219c80
leaq 0x27ae3(%rip), %rsi     # 0x190d5d
leaq -0x10(%rbp), %rdx
movb $0x0, %al
callq 0xd0d0
leaq 0x27add(%rip), %rax     # 0x190d69
movq %rax, -0x18(%rbp)
leaq 0x27bc7(%rip), %rax     # 0x190e5e
movq %rax, -0x20(%rbp)
leaq 0x27c94(%rip), %rax     # 0x190f36
movq %rax, -0x28(%rbp)
leaq 0x27ca2(%rip), %rax     # 0x190f4f
movq %rax, -0x30(%rbp)
leaq 0x27db1(%rip), %rax     # 0x191069
movq %rax, -0x38(%rbp)
leaq 0x27e72(%rip), %rax     # 0x191135
movq %rax, -0x40(%rbp)
leaq 0x27f07(%rip), %rax     # 0x1911d5
movq %rax, -0x48(%rbp)
leaq 0x27fcb(%rip), %rax     # 0x1912a4
movq %rax, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
cmpl $0x82, -0x10(%rbp)
jge 0x169308
movq -0x18(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x169352
cmpl $0x19a, -0x10(%rbp)     # imm = 0x19A
jl 0x169323
movq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x169350
cmpl $0x12c, -0x10(%rbp)     # imm = 0x12C
jne 0x16933e
movq -0x28(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x16934e
movq -0x20(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x169350
jmp 0x169352
leaq 0xb0927(%rip), %rax     # 0x219c80
movq %rax, -0x70(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x68(%rbp)
movl $0x8b31, %edi           # imm = 0x8B31
movq 0xa4c47(%rip), %rax     # 0x20dfb8
callq *(%rax)
movl %eax, 0xb092f(%rip)     # 0x219ca8
movq 0xa4bf0(%rip), %rax     # 0x20df70
movq (%rax), %rax
movl 0xb091f(%rip), %edi     # 0x219ca8
leaq -0x70(%rbp), %rdx
movl $0x2, %esi
xorl %ecx, %ecx
callq *%rax
movq 0xa4b83(%rip), %rax     # 0x20df20
movq (%rax), %rax
movl 0xb0902(%rip), %edi     # 0x219ca8
callq *%rax
movl 0xb08fa(%rip), %edi     # 0x219ca8
leaq 0x27fa5(%rip), %rsi     # 0x19135a
callq 0x16a0e0
leaq 0xb08bf(%rip), %rax     # 0x219c80
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x78(%rbp)
movl $0x8b30, %edi           # imm = 0x8B30
movq 0xa4bdf(%rip), %rax     # 0x20dfb8
callq *(%rax)
movl %eax, 0xb08cb(%rip)     # 0x219cac
movq 0xa4b88(%rip), %rax     # 0x20df70
movq (%rax), %rax
movl 0xb08bb(%rip), %edi     # 0x219cac
leaq -0x80(%rbp), %rdx
movl $0x2, %esi
xorl %ecx, %ecx
callq *%rax
movq 0xa4b1b(%rip), %rax     # 0x20df20
movq (%rax), %rax
movl 0xb089e(%rip), %edi     # 0x219cac
callq *%rax
movl 0xb0896(%rip), %edi     # 0x219cac
leaq 0x27f4b(%rip), %rsi     # 0x191368
callq 0x16a0e0
movq 0xa4acf(%rip), %rax     # 0x20def8
callq *(%rax)
movl %eax, 0xb086f(%rip)     # 0x219ca0
movq 0xa4b18(%rip), %rax     # 0x20df50
movq (%rax), %rax
movl 0xb085f(%rip), %edi     # 0x219ca0
movl 0xb0861(%rip), %esi     # 0x219ca8
callq *%rax
movq 0xa4b00(%rip), %rax     # 0x20df50
movq (%rax), %rax
movl 0xb0847(%rip), %edi     # 0x219ca0
movl 0xb084d(%rip), %esi     # 0x219cac
callq *%rax
movq 0xa4af8(%rip), %rax     # 0x20df60
movq (%rax), %rax
movl 0xb082f(%rip), %edi     # 0x219ca0
callq *%rax
movl 0xb0827(%rip), %edi     # 0x219ca0
leaq 0x27ef8(%rip), %rsi     # 0x191378
callq 0x16a230
movq 0xa4a1c(%rip), %rax     # 0x20dea8
movq (%rax), %rax
movl 0xb080b(%rip), %edi     # 0x219ca0
leaq 0x27eeb(%rip), %rsi     # 0x191387
callq *%rax
movl %eax, 0xb080c(%rip)     # 0x219cb0
movq 0xa49fd(%rip), %rax     # 0x20dea8
movq (%rax), %rax
movl 0xb07ec(%rip), %edi     # 0x219ca0
leaq 0x27ed4(%rip), %rsi     # 0x19138f
callq *%rax
movl %eax, 0xb07f1(%rip)     # 0x219cb4
movq 0xa4ade(%rip), %rax     # 0x20dfa8
movq (%rax), %rax
movl 0xb07cd(%rip), %edi     # 0x219ca0
leaq 0x10b3b(%rip), %rsi     # 0x17a015
callq *%rax
movl %eax, 0xb07d6(%rip)     # 0x219cb8
movq 0xa4abf(%rip), %rax     # 0x20dfa8
movq (%rax), %rax
movl 0xb07ae(%rip), %edi     # 0x219ca0
leaq 0x27e9e(%rip), %rsi     # 0x191397
callq *%rax
movl %eax, 0xb07bb(%rip)     # 0x219cbc
movq 0xa4aa0(%rip), %rax     # 0x20dfa8
movq (%rax), %rax
movl 0xb078f(%rip), %edi     # 0x219ca0
leaq 0x12e95(%rip), %rsi     # 0x17c3ad
callq *%rax
movl %eax, 0xb07a0(%rip)     # 0x219cc0
movl $0x1, %edi
leaq 0xb0798(%rip), %rsi     # 0x219cc4
movq 0xa49a5(%rip), %rax     # 0x20ded8
callq *(%rax)
movl $0x1, %edi
leaq 0xb0787(%rip), %rsi     # 0x219cc8
movq 0xa4990(%rip), %rax     # 0x20ded8
callq *(%rax)
callq 0x169f90
movl -0x4(%rbp), %esi
movl $0xde1, %edi            # imm = 0xDE1
callq 0xdab0
movq 0xa493d(%rip), %rax     # 0x20dea0
movq (%rax), %rax
movl -0x8(%rbp), %esi
movl $0x8892, %edi           # imm = 0x8892
callq *%rax
movq 0xa4a59(%rip), %rax     # 0x20dfd0
movq (%rax), %rax
movl -0xc(%rbp), %edi
callq *%rax
movb $0x1, %al
andb $0x1, %al
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)