// File: /workspace/github_c_makefile_star2_O1/FredTheDino[P]Fog/src/engine/renderer/opengl_renderer.cpp
// Function: Renderer::Impl::init(char const*, int, int)
b8 init(const char *title, int width, int height) {
    // Initalize the cameras zoom
    for (u32 i = 0; i < OPENGL_NUM_CAMERAS; i++) {
        _fog_global_window_state.cam[i].zoom = 1.0;
    }
    if (SDL_Init(SDL_INIT_EVERYTHING)) {
        ERR("Failed to initalize SDL");
        return false;
    }
    window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
            width, height, SDL_WINDOW_OPENGL);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    context = SDL_GL_CreateContext(window);

    if (!gladLoadGL()) {
        ERR("Failed to load OpenGL");
        return false;
    }
    resize_window(width, height);

    SDL::window_callback = resize_window;
    SDL_GL_SetSwapInterval(1);
    glEnable(GL_DEBUG_OUTPUT);
#if FOG_VERBOSE
    glDebugMessageCallback(gl_debug_message, 0);
#endif

    for (u32 i = 0; i < OPENGL_NUM_LAYERS; i++) {
        sprite_render_queues[i].create(512);
    }
    font_render_queue.create(256);

    // Initalize texture indicies
    for (u32 i = 0; i < OPENGL_NUM_CAMERAS; i++)
        _fog_texture_indicies[i] = i;

    glGenBuffers(1, &ubo_global);
    glBindBuffer(GL_UNIFORM_BUFFER, ubo_global);
    glBufferData(GL_UNIFORM_BUFFER, ubo_global_size, NULL, GL_STREAM_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, GLSL_GLOBAL_BLOCK, ubo_global);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    create_frame_buffers(width, height);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glGenTextures(1, &sprite_texture_array);
    glBindTexture(GL_TEXTURE_2D_ARRAY, sprite_texture_array);

    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, OPENGL_TEXTURE_WIDTH,
                   OPENGL_TEXTURE_HEIGHT, OPENGL_TEXTURE_DEPTH);

    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glActiveTexture(GL_TEXTURE0);

    // Set initial state
    glClearColor(0.3f, 0.1f, 0.2f, 1.0f);
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %ebx
movl %esi, %r14d
movq %rdi, %r15
xorl %eax, %eax
leaq 0x4ac3b(%rip), %rcx     # 0x6b250
movl $0x3f800000, 0x10(%rax,%rcx) # imm = 0x3F800000
addq $0x20, %rax
cmpq $0x20, %rax
je 0x20615
movl $0x7231, %edi           # imm = 0x7231
callq 0x2540
testl %eax, %eax
je 0x2066e
movq 0x2e994(%rip), %rax     # 0x4efd0
movq (%rax), %rsi
leaq 0x10669(%rip), %rdi     # 0x30caf
leaq 0x10a38(%rip), %rdx     # 0x31085
leaq 0x105a3(%rip), %r8      # 0x30bf7
leaq 0x10a7e(%rip), %r9      # 0x310d9
xorl %ebx, %ebx
movl $0x158, %ecx            # imm = 0x158
xorl %eax, %eax
callq 0x711f
jmp 0x208c4
movq %r15, %rdi
movl $0x1fff0000, %esi       # imm = 0x1FFF0000
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
movl %r14d, %ecx
movl %ebx, %r8d
movl $0x2, %r9d
callq 0x2260
leaq 0x4ab9d(%rip), %r15     # 0x6b230
movq %rax, (%r15)
movl $0x11, %edi
movl $0x3, %esi
callq 0x24a0
movl $0x12, %edi
movl $0x3, %esi
callq 0x24a0
movl $0x15, %edi
movl $0x1, %esi
callq 0x24a0
movq (%r15), %rdi
callq 0x2360
leaq 0x4ab66(%rip), %rcx     # 0x6b238
movq %rax, (%rcx)
callq 0xc0ba
testl %eax, %eax
je 0x208d5
movl %r14d, %edi
movl %ebx, %esi
callq 0x200b8
leaq -0x63b(%rip), %rax      # 0x200b8
leaq 0x30216(%rip), %rcx     # 0x50910
movq %rax, (%rcx)
movl $0x1, %edi
callq 0x22d0
leaq 0x4472a(%rip), %r15     # 0x64e38
movl $0x92e0, %edi           # imm = 0x92E0
callq *(%r15)
xorl %r12d, %r12d
leaq 0x4a8c0(%rip), %r13     # 0x6afe0
leaq (%r12,%r13), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x2df92
addq $0x20, %r12
cmpq $0x200, %r12            # imm = 0x200
jne 0x20720
leaq 0x4aa9e(%rip), %rdi     # 0x6b1e0
movl $0x100, %esi            # imm = 0x100
callq 0x2dffe
leaq 0x4aaf1(%rip), %rax     # 0x6b244
xorl %ecx, %ecx
movl %ecx, (%rax)
incq %rcx
addq $0x4, %rax
cmpq $0x1, %rcx
je 0x20755
leaq 0x44825(%rip), %rax     # 0x64f90
leaq 0x4ab2e(%rip), %rsi     # 0x6b2a0
movl $0x1, %edi
callq *(%rax)
leaq 0x44300(%rip), %r12     # 0x64a80
movl 0x4ab1a(%rip), %esi     # 0x6b2a0
movl $0x8a11, %edi           # imm = 0x8A11
callq *(%r12)
leaq 0x44362(%rip), %rax     # 0x64af8
movl $0x50, %esi
movl $0x8a11, %edi           # imm = 0x8A11
xorl %edx, %edx
movl $0x88e0, %ecx           # imm = 0x88E0
callq *(%rax)
leaq 0x442d8(%rip), %rax     # 0x64a88
movl 0x4aaea(%rip), %edx     # 0x6b2a0
movl $0x8a11, %edi           # imm = 0x8A11
xorl %esi, %esi
callq *(%rax)
movl $0x8a11, %edi           # imm = 0x8A11
xorl %esi, %esi
callq *(%r12)
movl %r14d, %edi
movl %ebx, %esi
callq 0x20224
movl $0xbe2, %edi            # imm = 0xBE2
callq *(%r15)
leaq 0x442fd(%rip), %rax     # 0x64ae0
movl $0x302, %edi            # imm = 0x302
movl $0x303, %esi            # imm = 0x303
callq *(%rax)
leaq 0x447c2(%rip), %rax     # 0x64fb8
leaq 0x4aa03(%rip), %rbx     # 0x6b200
movl $0x1, %edi
movq %rbx, %rsi
callq *(%rax)
leaq 0x442a2(%rip), %rax     # 0x64ab0
movl (%rbx), %esi
movl $0x8c1a, %edi           # imm = 0x8C1A
callq *(%rax)
leaq 0x473b2(%rip), %rax     # 0x67bd0
movl $0x8c1a, %edi           # imm = 0x8C1A
movl $0x1, %esi
movl $0x8058, %edx           # imm = 0x8058
movl $0x200, %ecx            # imm = 0x200
movl $0x200, %r8d            # imm = 0x200
movl $0x100, %r9d            # imm = 0x100
callq *(%rax)
leaq 0x45221(%rip), %rbx     # 0x65a68
movl $0x8c1a, %edi           # imm = 0x8C1A
movl $0x2801, %esi           # imm = 0x2801
movl $0x2601, %edx           # imm = 0x2601
callq *(%rbx)
movl $0x8c1a, %edi           # imm = 0x8C1A
movl $0x2800, %esi           # imm = 0x2800
movl $0x2601, %edx           # imm = 0x2601
callq *(%rbx)
movl $0x8c1a, %edi           # imm = 0x8C1A
movl $0x2802, %esi           # imm = 0x2802
movl $0x812f, %edx           # imm = 0x812F
callq *(%rbx)
movl $0x8c1a, %edi           # imm = 0x8C1A
movl $0x2803, %esi           # imm = 0x2803
movl $0x812f, %edx           # imm = 0x812F
callq *(%rbx)
leaq 0x4419e(%rip), %rax     # 0x64a30
movl $0x84c0, %edi           # imm = 0x84C0
callq *(%rax)
leaq 0x442b8(%rip), %rax     # 0x64b58
movss 0xf994(%rip), %xmm0     # 0x3023c
movss 0xf97c(%rip), %xmm1     # 0x3022c
movss 0xf754(%rip), %xmm2     # 0x3000c
movss 0xf744(%rip), %xmm3     # 0x30004
callq *(%rax)
movb $0x1, %bl
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2e6f4(%rip), %rax     # 0x4efd0
movq (%rax), %rsi
leaq 0x103c9(%rip), %rdi     # 0x30caf
leaq 0x10798(%rip), %rdx     # 0x31085
leaq 0x10303(%rip), %r8      # 0x30bf7
leaq 0x107f6(%rip), %r9      # 0x310f1
xorl %ebx, %ebx
movl $0x165, %ecx            # imm = 0x165
jmp 0x20662