// File: /workspace/github_c_makefile_star2_O0/FredTheDino[P]Fog/src/engine/renderer/opengl_renderer.cpp
// Function: Renderer::Impl::compile_shader_program_from_source(char const*)
static Program compile_shader_program_from_source(const char *source) {
#define SHADER_ERROR_CHECK(SHDR)                             \
    do {                                                     \
        GLint success = 0;                                   \
        glGetShaderiv(SHDR, GL_COMPILE_STATUS, &success);    \
        if (success == GL_FALSE) {                           \
            char buffer[512];                                \
            glGetShaderInfoLog(SHDR, 500, NULL, &buffer[0]); \
            ERR("%s: %s\n", "\"" #SHDR "\"", buffer);        \
            glDeleteShader(frag);                            \
            glDeleteShader(vert);                            \
            return Program::invalid_prog();                         \
        }                                                    \
    } while (false);

    u32 frag = glCreateShader(GL_FRAGMENT_SHADER);
    u32 vert = glCreateShader(GL_VERTEX_SHADER);

    const char *complete_source[] = {
        "#version 330\n",
        "#define VERT\n",
        "struct Camera\n"
        "{\n"
        "    vec2  pos;\n"
        "    vec2  offset;\n"
        "    float zoom;\n"
        "    float aspect_ratio;\n"
        "};"
        "struct Window\n"
        "{\n"
        "    float width;\n"
        "    float height;\n"
        "    float aspect_ratio;\n"
        "};"
        "layout (std140) uniform Global\n"
        "{\n"
        "   Camera cam[" STR(OPENGL_NUM_CAMERAS) "];\n"
        "   Window win;\n"
        "};\n"
        "uniform uint current_cam;\n"
        ,
        source};
    glShaderSource(vert, LEN(complete_source), complete_source, NULL);
    glCompileShader(vert);
    SHADER_ERROR_CHECK(vert);

    complete_source[1] = "#define FRAG\n";
    glShaderSource(frag, LEN(complete_source), complete_source, NULL);
    glCompileShader(frag);
    SHADER_ERROR_CHECK(frag);

    Program shader = {(s32) glCreateProgram()};
    glAttachShader(shader.id, vert);
    glAttachShader(shader.id, frag);
    glLinkProgram(shader.id);

    glDeleteShader(frag);
    glDeleteShader(vert);

    GLint success = 0;
    glGetProgramiv(shader.id, GL_LINK_STATUS, &success);
    if (success == GL_FALSE) {
        char buffer[512];
        glGetProgramInfoLog(shader.id, 500, NULL, &buffer[0]);
        ERR("Program: %s\n", buffer);
        return Program::invalid_prog();
    }

    unsigned int block = glGetUniformBlockIndex(shader, "Camera");
    glUniformBlockBinding(shader, block, GLSL_GLOBAL_BLOCK);

    return shader;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x6a0, %rsp            # imm = 0x6A0
movq %rdi, -0x10(%rbp)
movl $0x8b30, %edi           # imm = 0x8B30
leaq 0x51cad(%rip), %rax     # 0x7ed58
callq *(%rax)
movl %eax, -0x14(%rbp)
movl $0x8b31, %edi           # imm = 0x8B31
leaq 0x51c9c(%rip), %rax     # 0x7ed58
callq *(%rax)
movl %eax, -0x18(%rbp)
leaq 0x2d625(%rip), %rax     # 0x5a6ed
movq %rax, -0x40(%rbp)
leaq 0x2d628(%rip), %rax     # 0x5a6fb
movq %rax, -0x38(%rbp)
leaq 0x2d62b(%rip), %rax     # 0x5a709
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq 0x527c7(%rip), %rax     # 0x7f8b8
movq (%rax), %rax
movl -0x18(%rbp), %edi
leaq -0x40(%rbp), %rdx
movl $0x4, %esi
xorl %ecx, %ecx
callq *%rax
leaq 0x51bd5(%rip), %rax     # 0x7ece0
movq (%rax), %rax
movl -0x18(%rbp), %edi
callq *%rax
movl $0x0, -0x44(%rbp)
leaq 0x5204f(%rip), %rax     # 0x7f170
movq (%rax), %rax
movl -0x18(%rbp), %edi
movl $0x8b81, %esi           # imm = 0x8B81
leaq -0x44(%rbp), %rdx
callq *%rax
cmpl $0x0, -0x44(%rbp)
jne 0x2d1cd
leaq 0x5201d(%rip), %rax     # 0x7f160
movq (%rax), %rax
movl -0x18(%rbp), %edi
leaq -0x250(%rbp), %rcx
movl $0x1f4, %esi            # imm = 0x1F4
xorl %edx, %edx
callq *%rax
movq 0x3be80(%rip), %rax     # 0x68fe0
movq (%rax), %rsi
leaq -0x250(%rbp), %rax
leaq 0x18afe(%rip), %rdi     # 0x45c6f
leaq 0x18ecd(%rip), %rdx     # 0x46045
movl $0x34, %ecx
leaq 0x2d68d(%rip), %r8      # 0x5a811
leaq 0x2d6a9(%rip), %r9      # 0x5a834
leaq 0x2d6aa(%rip), %r10     # 0x5a83c
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0xb100
leaq 0x51bef(%rip), %rax     # 0x7ed98
movq (%rax), %rax
movl -0x14(%rbp), %edi
callq *%rax
leaq 0x51be0(%rip), %rax     # 0x7ed98
movq (%rax), %rax
movl -0x18(%rbp), %edi
callq *%rax
callq 0x43b30
movl %eax, -0x4(%rbp)
jmp 0x2d43d
jmp 0x2d1cf
leaq 0x2d66d(%rip), %rax     # 0x5a843
movq %rax, -0x38(%rbp)
leaq 0x526d7(%rip), %rax     # 0x7f8b8
movq (%rax), %rax
movl -0x14(%rbp), %edi
leaq -0x40(%rbp), %rdx
movl $0x4, %esi
xorl %ecx, %ecx
callq *%rax
leaq 0x51ae5(%rip), %rax     # 0x7ece0
movq (%rax), %rax
movl -0x14(%rbp), %edi
callq *%rax
movl $0x0, -0x254(%rbp)
leaq 0x51f5c(%rip), %rax     # 0x7f170
movq (%rax), %rax
movl -0x14(%rbp), %edi
movl $0x8b81, %esi           # imm = 0x8B81
leaq -0x254(%rbp), %rdx
callq *%rax
cmpl $0x0, -0x254(%rbp)
jne 0x2d2c6
leaq 0x51f24(%rip), %rax     # 0x7f160
movq (%rax), %rax
movl -0x14(%rbp), %edi
leaq -0x460(%rbp), %rcx
movl $0x1f4, %esi            # imm = 0x1F4
xorl %edx, %edx
callq *%rax
movq 0x3bd87(%rip), %rax     # 0x68fe0
movq (%rax), %rsi
leaq -0x460(%rbp), %rax
leaq 0x18a05(%rip), %rdi     # 0x45c6f
leaq 0x18dd4(%rip), %rdx     # 0x46045
movl $0x39, %ecx
leaq 0x2d594(%rip), %r8      # 0x5a811
leaq 0x2d5b0(%rip), %r9      # 0x5a834
leaq 0x2d5c6(%rip), %r10     # 0x5a851
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0xb100
leaq 0x51af6(%rip), %rax     # 0x7ed98
movq (%rax), %rax
movl -0x14(%rbp), %edi
callq *%rax
leaq 0x51ae7(%rip), %rax     # 0x7ed98
movq (%rax), %rax
movl -0x18(%rbp), %edi
callq *%rax
callq 0x43b30
movl %eax, -0x4(%rbp)
jmp 0x2d43d
jmp 0x2d2c8
leaq 0x51a81(%rip), %rax     # 0x7ed50
callq *(%rax)
movl %eax, -0x464(%rbp)
leaq 0x517a2(%rip), %rax     # 0x7ea80
movq (%rax), %rax
movl -0x464(%rbp), %edi
movl -0x18(%rbp), %esi
callq *%rax
leaq 0x5178d(%rip), %rax     # 0x7ea80
movq (%rax), %rax
movl -0x464(%rbp), %edi
movl -0x14(%rbp), %esi
callq *%rax
leaq 0x52078(%rip), %rax     # 0x7f380
movq (%rax), %rax
movl -0x464(%rbp), %edi
callq *%rax
leaq 0x51a7e(%rip), %rax     # 0x7ed98
movq (%rax), %rax
movl -0x14(%rbp), %edi
callq *%rax
leaq 0x51a6f(%rip), %rax     # 0x7ed98
movq (%rax), %rax
movl -0x18(%rbp), %edi
callq *%rax
movl $0x0, -0x468(%rbp)
leaq 0x51df6(%rip), %rax     # 0x7f138
movq (%rax), %rax
movl -0x464(%rbp), %edi
movl $0x8b82, %esi           # imm = 0x8B82
leaq -0x468(%rbp), %rdx
callq *%rax
cmpl $0x0, -0x468(%rbp)
jne 0x2d3c9
leaq 0x51dc7(%rip), %rax     # 0x7f130
movq (%rax), %rax
movl -0x464(%rbp), %edi
leaq -0x670(%rbp), %rcx
movl $0x1f4, %esi            # imm = 0x1F4
xorl %edx, %edx
callq *%rax
movq 0x3bc57(%rip), %rax     # 0x68fe0
movq (%rax), %rsi
leaq -0x670(%rbp), %rax
leaq 0x188d5(%rip), %rdi     # 0x45c6f
leaq 0x18ca4(%rip), %rdx     # 0x46045
movl $0x48, %ecx
leaq 0x2d464(%rip), %r8      # 0x5a811
leaq 0x2d4a4(%rip), %r9      # 0x5a858
movq %rax, (%rsp)
movb $0x0, %al
callq 0xb100
callq 0x43b30
movl %eax, -0x4(%rbp)
jmp 0x2d43d
leaq 0x51e28(%rip), %rax     # 0x7f1f8
movq (%rax), %rax
movq %rax, -0x688(%rbp)
leaq -0x464(%rbp), %rdi
callq 0x41e60
movb %al, %cl
movq -0x688(%rbp), %rax
movzbl %cl, %edi
leaq 0x2d46c(%rip), %rsi     # 0x5a865
callq *%rax
movl %eax, -0x674(%rbp)
leaq 0x52790(%rip), %rax     # 0x7fb98
movq (%rax), %rax
movq %rax, -0x680(%rbp)
leaq -0x464(%rbp), %rdi
callq 0x41e60
movb %al, %cl
movq -0x680(%rbp), %rax
movzbl %cl, %edi
movl -0x674(%rbp), %esi
xorl %edx, %edx
callq *%rax
movl -0x464(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x6a0, %rsp            # imm = 0x6A0
popq %rbp
retq
nopl (%rax)