// File: /workspace/github_c_makefile_star2_O2/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 0x4756d(%rip), %rcx     # 0x6624c
cmpq $0x40, %rax
je 0x1ecf3
movl $0x3f800000, 0x10(%rax,%rcx) # imm = 0x3F800000
addq $0x20, %rax
jmp 0x1ecdf
movl $0x7231, %edi           # imm = 0x7231
callq 0x2530
testl %eax, %eax
je 0x1ed3a
movq 0x2b2c8(%rip), %rax     # 0x49fd0
movq (%rax), %rsi
leaq 0xcf65(%rip), %rdi      # 0x2bc77
leaq 0xd334(%rip), %rdx      # 0x2c04d
leaq 0xce9f(%rip), %r8       # 0x2bbbf
leaq 0xd37a(%rip), %r9       # 0x2c0a1
xorl %ebx, %ebx
movl $0x158, %ecx            # imm = 0x158
xorl %eax, %eax
callq 0x683a
jmp 0x1ef7f
pushq $0x2
popq %r9
movq %r15, %rdi
movl $0x1fff0000, %esi       # imm = 0x1FFF0000
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
movl %r14d, %ecx
movl %ebx, %r8d
callq 0x2260
leaq 0x474d3(%rip), %r12     # 0x66230
movq %rax, (%r12)
pushq $0x11
popq %rdi
pushq $0x3
popq %r15
movl %r15d, %esi
callq 0x2490
pushq $0x12
popq %rdi
movl %r15d, %esi
callq 0x2490
pushq $0x15
popq %rdi
pushq $0x1
popq %rsi
callq 0x2490
movq (%r12), %rdi
callq 0x2360
leaq 0x474a2(%rip), %rcx     # 0x66238
movq %rax, (%rcx)
callq 0xa7ef
testl %eax, %eax
je 0x1ef90
movl %r14d, %edi
movl %ebx, %esi
callq 0x1e7b5
leaq -0x602(%rip), %rax      # 0x1e7b5
leaq 0x2cb52(%rip), %rcx     # 0x4b910
movq %rax, (%rcx)
pushq $0x1
popq %rdi
callq 0x22d0
leaq 0x41068(%rip), %r12     # 0x5fe38
movl $0x92e0, %edi           # imm = 0x92E0
callq *(%r12)
xorl %r15d, %r15d
leaq 0x471fd(%rip), %r13     # 0x65fe0
cmpq $0x200, %r15            # imm = 0x200
je 0x1ee00
leaq (%r15,%r13), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x295c0
addq $0x20, %r15
jmp 0x1ede3
leaq 0x473d9(%rip), %rdi     # 0x661e0
movl $0x100, %esi            # imm = 0x100
callq 0x29626
movabsq $0x100000000, %rax      # imm = 0x100000000
movq %rax, 0x47422(%rip)     # 0x66244
leaq 0x41167(%rip), %rax     # 0x5ff90
leaq 0x4746c(%rip), %rsi     # 0x6629c
pushq $0x1
popq %r15
movl %r15d, %edi
callq *(%rax)
leaq 0x40c40(%rip), %r13     # 0x5fa80
movl 0x47456(%rip), %esi     # 0x6629c
movl $0x8a11, %edi           # imm = 0x8A11
callq *(%r13)
leaq 0x40ca2(%rip), %rax     # 0x5faf8
pushq $0x50
popq %rsi
movl $0x8a11, %edi           # imm = 0x8A11
xorl %edx, %edx
movl $0x88e0, %ecx           # imm = 0x88E0
callq *(%rax)
leaq 0x40c1a(%rip), %rax     # 0x5fa88
movl 0x47428(%rip), %edx     # 0x6629c
movl $0x8a11, %edi           # imm = 0x8A11
xorl %esi, %esi
callq *(%rax)
movl $0x8a11, %edi           # imm = 0x8A11
xorl %esi, %esi
callq *(%r13)
movl %r14d, %edi
movl %ebx, %esi
callq 0x1e8f0
movl $0xbe2, %edi            # imm = 0xBE2
callq *(%r12)
leaq 0x40c3e(%rip), %rax     # 0x5fae0
movl $0x302, %edi            # imm = 0x302
movl $0x303, %esi            # imm = 0x303
callq *(%rax)
leaq 0x41103(%rip), %rax     # 0x5ffb8
leaq 0x47344(%rip), %rbx     # 0x66200
movl %r15d, %edi
movq %rbx, %rsi
callq *(%rax)
leaq 0x40be5(%rip), %rax     # 0x5fab0
movl (%rbx), %esi
movl $0x8c1a, %edi           # imm = 0x8C1A
callq *(%rax)
leaq 0x43cf5(%rip), %rax     # 0x62bd0
movl $0x8c1a, %edi           # imm = 0x8C1A
movl %r15d, %esi
movl $0x8058, %edx           # imm = 0x8058
movl $0x200, %ecx            # imm = 0x200
movl $0x200, %r8d            # imm = 0x200
movl $0x100, %r9d            # imm = 0x100
callq *(%rax)
leaq 0x41b66(%rip), %rbx     # 0x60a68
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 0x40ae3(%rip), %rax     # 0x5fa30
movl $0x84c0, %edi           # imm = 0x84C0
callq *(%rax)
leaq 0x40bfd(%rip), %rax     # 0x5fb58
movss 0xc2d9(%rip), %xmm0     # 0x2b23c
movss 0xc2c5(%rip), %xmm1     # 0x2b230
movss 0xc099(%rip), %xmm2     # 0x2b00c
movss 0xc089(%rip), %xmm3     # 0x2b004
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 0x2b039(%rip), %rax     # 0x49fd0
movq (%rax), %rsi
leaq 0xccd6(%rip), %rdi      # 0x2bc77
leaq 0xd0a5(%rip), %rdx      # 0x2c04d
leaq 0xcc10(%rip), %r8       # 0x2bbbf
leaq 0xd103(%rip), %r9       # 0x2c0b9
xorl %ebx, %ebx
movl $0x165, %ecx            # imm = 0x165
jmp 0x1ed2e