// File: /workspace/github_c_makefile_star2_O3/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
movl $0x3f800000, %eax       # imm = 0x3F800000
movl %eax, 0x4aeff(%rip)     # 0x6b250
movl %eax, 0x4af19(%rip)     # 0x6b270
movl $0x7231, %edi           # imm = 0x7231
callq 0x2530
testl %eax, %eax
je 0x2039e
movq 0x2ec64(%rip), %rax     # 0x4efd0
movq (%rax), %rsi
leaq 0x10929(%rip), %rdi     # 0x30c9f
leaq 0x10cf8(%rip), %rdx     # 0x31075
leaq 0x10863(%rip), %r8      # 0x30be7
leaq 0x10d3e(%rip), %r9      # 0x310c9
xorl %ebx, %ebx
movl $0x158, %ecx            # imm = 0x158
xorl %eax, %eax
callq 0x718c
jmp 0x205ed
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 0x4ae5d(%rip), %r15     # 0x6b220
movq %rax, (%r15)
movl $0x11, %edi
movl $0x3, %esi
callq 0x2490
movl $0x12, %edi
movl $0x3, %esi
callq 0x2490
movl $0x15, %edi
movl $0x1, %esi
callq 0x2490
movq (%r15), %rdi
callq 0x2360
leaq 0x4ae26(%rip), %rcx     # 0x6b228
movq %rax, (%rcx)
callq 0xbdbb
testl %eax, %eax
je 0x205fe
movl %r14d, %edi
movl %ebx, %esi
callq 0x1fdd4
leaq -0x64f(%rip), %rax      # 0x1fdd4
leaq 0x304d6(%rip), %rcx     # 0x50900
movq %rax, (%rcx)
movl $0x1, %edi
callq 0x22d0
leaq 0x449ea(%rip), %r15     # 0x64e28
movl $0x92e0, %edi           # imm = 0x92E0
callq *(%r15)
xorl %r12d, %r12d
leaq 0x4ab80(%rip), %r13     # 0x6afd0
leaq (%r12,%r13), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x2d816
addq $0x20, %r12
cmpq $0x200, %r12            # imm = 0x200
jne 0x20450
leaq 0x4ad5e(%rip), %rdi     # 0x6b1d0
movl $0x100, %esi            # imm = 0x100
callq 0x2d882
movabsq $0x100000000, %rax      # imm = 0x100000000
movq %rax, 0x4ada7(%rip)     # 0x6b234
leaq 0x44aec(%rip), %rax     # 0x64f80
leaq 0x4adf5(%rip), %rsi     # 0x6b290
movl $0x1, %edi
callq *(%rax)
leaq 0x445c7(%rip), %r12     # 0x64a70
movl 0x4ade1(%rip), %esi     # 0x6b290
movl $0x8a11, %edi           # imm = 0x8A11
callq *(%r12)
leaq 0x44629(%rip), %rax     # 0x64ae8
movl $0x50, %esi
movl $0x8a11, %edi           # imm = 0x8A11
xorl %edx, %edx
movl $0x88e0, %ecx           # imm = 0x88E0
callq *(%rax)
leaq 0x4459f(%rip), %rax     # 0x64a78
movl 0x4adb1(%rip), %edx     # 0x6b290
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 0x1ff56
movl $0xbe2, %edi            # imm = 0xBE2
callq *(%r15)
leaq 0x445c4(%rip), %rax     # 0x64ad0
movl $0x302, %edi            # imm = 0x302
movl $0x303, %esi            # imm = 0x303
callq *(%rax)
leaq 0x44a89(%rip), %rax     # 0x64fa8
leaq 0x4acca(%rip), %rbx     # 0x6b1f0
movl $0x1, %edi
movq %rbx, %rsi
callq *(%rax)
leaq 0x44569(%rip), %rax     # 0x64aa0
movl (%rbx), %esi
movl $0x8c1a, %edi           # imm = 0x8C1A
callq *(%rax)
leaq 0x47679(%rip), %rax     # 0x67bc0
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 0x454e8(%rip), %rbx     # 0x65a58
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 0x44465(%rip), %rax     # 0x64a20
movl $0x84c0, %edi           # imm = 0x84C0
callq *(%rax)
leaq 0x4457f(%rip), %rax     # 0x64b48
movss 0xfc6b(%rip), %xmm0     # 0x3023c
movss 0xfc53(%rip), %xmm1     # 0x3022c
movss 0xfa2b(%rip), %xmm2     # 0x3000c
movss 0xfa1b(%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 0x2e9cb(%rip), %rax     # 0x4efd0
movq (%rax), %rsi
leaq 0x10690(%rip), %rdi     # 0x30c9f
leaq 0x10a5f(%rip), %rdx     # 0x31075
leaq 0x105ca(%rip), %r8      # 0x30be7
leaq 0x10abd(%rip), %r9      # 0x310e1
xorl %ebx, %ebx
movl $0x165, %ecx            # imm = 0x165
jmp 0x20392