// File: SpiritLooper[P]RDV_OBJRender/obj_render.cpp
// Function: render(Model*, bool)
void render(Model* model, bool _3D) {
   
    float* zbuffer = new float[width * height];
    float* zbuffer_red = new float[width * height];
    float* zbuffer_blue = new float[width * height];
    
    for (int i = 0; i < width * height; i++)
    {
        zbuffer[i] = -std::numeric_limits<float>::max();
        zbuffer_blue[i] = -std::numeric_limits<float>::max();
        zbuffer_red[i] = -std::numeric_limits<float>::max();
    }
    
    Image img(width , height);  
    Image img_red(width , height);  
    Image img_blue(width , height);  

    Camera cam(camera_pos, img, PERSPECTIVE);

    std::cout << "Drawing triangle " ; 

    //Dessin des triangles du model
    for (int i = 0; i < model->nfaces() ; i++)
    {
        std::vector<int> face = model->face(i); 
        Vec3f screen_coords[3];
        Vec3f world_coords[3]; 

        Vec3f screen_coords_left_eye[3];
        Vec3f screen_coords_right_eye[3];

        for (int j=0; j<3; j++) { 
            Vec3f v = model->vert(face[j]); 
            screen_coords[j] = cam.camera_transform(v);

            cam.camera_transform_analygraph(v, screen_coords_left_eye[j], screen_coords_right_eye[j] );

            world_coords[j]  = v; 
        }

        Vec3f norm_triangle = (world_coords[2] - world_coords[0]) ^ (world_coords[1] - world_coords[0]);
        norm_triangle.normalize();
        float intensity = norm_triangle * light_dir;
        
        if(_3D) {
            triangle(screen_coords_left_eye,  zbuffer_red, img_red, Vec3f(intensity, 0, 0));
            triangle(screen_coords_right_eye, zbuffer_blue, img_blue, Vec3f(0, 0, intensity));
        } else {
            triangle(screen_coords, zbuffer, img, Vec3f(intensity, intensity, intensity));
        }
        
    }
    if(_3D) 
        img = img_red.fusionner(img_blue);

    std::cout << "\nFliping image ..." << std::endl; 
    img.flip(VERTICAL_FLIP);

    std::cout << "PPM exporting ..." << std::endl;
    img.exportPPM(); 

    std::cout << "Done" << std::endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4e0, %rsp            # imm = 0x4E0
movb %sil, %al
movq %rdi, -0x8(%rbp)
andb $0x1, %al
movb %al, -0x9(%rbp)
movl $0x300000, %edi         # imm = 0x300000
callq 0x2040
movq %rax, -0x18(%rbp)
movl $0x300000, %edi         # imm = 0x300000
callq 0x2040
movq %rax, -0x20(%rbp)
movl $0x300000, %edi         # imm = 0x300000
callq 0x2040
movq %rax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
cmpl $0xc0000, -0x2c(%rbp)   # imm = 0xC0000
jge 0xdba9
callq 0xe830
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movq -0x18(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movss %xmm0, (%rax,%rcx,4)
callq 0xe830
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movss %xmm0, (%rax,%rcx,4)
callq 0xe830
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movss %xmm0, (%rax,%rcx,4)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xdb38
leaq -0x50(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
movl %esi, -0x398(%rbp)
movl $0x300, %edx            # imm = 0x300
movl %edx, -0x394(%rbp)
callq 0x6550
movl -0x398(%rbp), %esi
movl -0x394(%rbp), %edx
leaq -0x70(%rbp), %rdi
callq 0x6550
jmp 0xdbdf
leaq -0xa0(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
movl $0x300, %edx            # imm = 0x300
callq 0x6550
jmp 0xdbf7
movl 0x8633(%rip), %eax      # 0x16230
movl %eax, -0x118(%rbp)
movq 0x861e(%rip), %rax      # 0x16228
movq %rax, -0x120(%rbp)
leaq -0x140(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0xe8e0
jmp 0xdc23
movl -0x118(%rbp), %eax
movl %eax, -0x148(%rbp)
movq -0x120(%rbp), %rax
movq %rax, -0x150(%rbp)
movsd -0x150(%rbp), %xmm0
movss -0x148(%rbp), %xmm1
leaq -0x110(%rbp), %rdi
leaq -0x140(%rbp), %rsi
movl $0x1, %edx
callq 0x4820
jmp 0xdc67
leaq -0x140(%rbp), %rdi
callq 0x65e0
movq 0x835e(%rip), %rdi      # 0x15fd8
leaq 0x157f(%rip), %rsi      # 0xf200
callq 0x21f0
jmp 0xdc88
movl $0x0, -0x154(%rbp)
movl -0x154(%rbp), %eax
movl %eax, -0x3a0(%rbp)
movq -0x8(%rbp), %rdi
callq 0x8eb0
movl %eax, -0x39c(%rbp)
jmp 0xdcaf
movl -0x3a0(%rbp), %eax
movl -0x39c(%rbp), %ecx
cmpl %ecx, %eax
jge 0xe383
movq -0x8(%rbp), %rsi
movl -0x154(%rbp), %edx
leaq -0x170(%rbp), %rdi
callq 0x8ed0
jmp 0xdcdb
leaq -0x1a0(%rbp), %rax
movq %rax, %rcx
addq $0x24, %rcx
movq %rcx, -0x3b0(%rbp)
movq %rax, -0x3a8(%rbp)
movq -0x3a8(%rbp), %rdi
movq %rdi, -0x3b8(%rbp)
callq 0x5b90
jmp 0xdd0c
movq -0x3b0(%rbp), %rcx
movq -0x3b8(%rbp), %rax
addq $0xc, %rax
cmpq %rcx, %rax
movq %rax, -0x3a8(%rbp)
jne 0xdcf7
leaq -0x1d0(%rbp), %rax
movq %rax, %rcx
addq $0x24, %rcx
movq %rcx, -0x3c8(%rbp)
movq %rax, -0x3c0(%rbp)
movq -0x3c0(%rbp), %rdi
movq %rdi, -0x3d0(%rbp)
callq 0x5b90
jmp 0xdd5b
movq -0x3c8(%rbp), %rcx
movq -0x3d0(%rbp), %rax
addq $0xc, %rax
cmpq %rcx, %rax
movq %rax, -0x3c0(%rbp)
jne 0xdd46
leaq -0x200(%rbp), %rax
movq %rax, %rcx
addq $0x24, %rcx
movq %rcx, -0x3e0(%rbp)
movq %rax, -0x3d8(%rbp)
movq -0x3d8(%rbp), %rdi
movq %rdi, -0x3e8(%rbp)
callq 0x5b90
jmp 0xddaa
movq -0x3e0(%rbp), %rcx
movq -0x3e8(%rbp), %rax
addq $0xc, %rax
cmpq %rcx, %rax
movq %rax, -0x3d8(%rbp)
jne 0xdd95
leaq -0x230(%rbp), %rax
movq %rax, %rcx
addq $0x24, %rcx
movq %rcx, -0x3f8(%rbp)
movq %rax, -0x3f0(%rbp)
movq -0x3f0(%rbp), %rdi
movq %rdi, -0x400(%rbp)
callq 0x5b90
jmp 0xddf9
movq -0x3f8(%rbp), %rcx
movq -0x400(%rbp), %rax
addq $0xc, %rax
cmpq %rcx, %rax
movq %rax, -0x3f0(%rbp)
jne 0xdde4
movl $0x0, -0x234(%rbp)
cmpl $0x3, -0x234(%rbp)
jge 0xe090
movq -0x8(%rbp), %rax
movq %rax, -0x420(%rbp)
movslq -0x234(%rbp), %rsi
leaq -0x170(%rbp), %rdi
callq 0xe920
movq -0x420(%rbp), %rdi
movl (%rax), %esi
callq 0x8f20
movss %xmm1, -0x414(%rbp)
movaps %xmm0, -0x410(%rbp)
jmp 0xde6b
movss -0x414(%rbp), %xmm0
movaps -0x410(%rbp), %xmm1
movlpd %xmm1, -0x250(%rbp)
movss %xmm0, -0x248(%rbp)
movl -0x248(%rbp), %eax
movl %eax, -0x238(%rbp)
movq -0x250(%rbp), %rax
movq %rax, -0x240(%rbp)
movl -0x238(%rbp), %eax
movl %eax, -0x268(%rbp)
movq -0x240(%rbp), %rax
movq %rax, -0x270(%rbp)
movl -0x268(%rbp), %eax
movl %eax, -0x278(%rbp)
movq -0x270(%rbp), %rax
movq %rax, -0x280(%rbp)
movsd -0x280(%rbp), %xmm0
movss -0x278(%rbp), %xmm1
leaq -0x110(%rbp), %rdi
callq 0x5400
movss %xmm1, -0x434(%rbp)
movaps %xmm0, -0x430(%rbp)
jmp 0xdf05
movss -0x434(%rbp), %xmm0
movaps -0x430(%rbp), %xmm1
movlpd %xmm1, -0x290(%rbp)
movss %xmm0, -0x288(%rbp)
movl -0x288(%rbp), %eax
movl %eax, -0x258(%rbp)
movq -0x290(%rbp), %rax
movq %rax, -0x260(%rbp)
movslq -0x234(%rbp), %rax
leaq (%rax,%rax,2), %rax
movl -0x258(%rbp), %ecx
movl %ecx, -0x198(%rbp,%rax,4)
movq -0x260(%rbp), %rcx
movq %rcx, -0x1a0(%rbp,%rax,4)
movl -0x238(%rbp), %eax
movl %eax, -0x298(%rbp)
movq -0x240(%rbp), %rax
movq %rax, -0x2a0(%rbp)
movslq -0x234(%rbp), %rax
shlq $0x2, %rax
leaq (%rax,%rax,2), %rax
leaq -0x200(%rbp,%rax), %rsi
leaq -0x230(%rbp,%rax), %rdx
movl -0x298(%rbp), %eax
movl %eax, -0x2a8(%rbp)
movq -0x2a0(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movsd -0x2b0(%rbp), %xmm0
movss -0x2a8(%rbp), %xmm1
leaq -0x110(%rbp), %rdi
callq 0x5670
jmp 0xdfd6
movslq -0x234(%rbp), %rcx
leaq -0x1d0(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq -0x240(%rbp), %rcx
movq %rcx, (%rax)
movl -0x238(%rbp), %ecx
movl %ecx, 0x8(%rax)
movl -0x234(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x234(%rbp)
jmp 0xde21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe4de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe4d5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe4c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x65e0
jmp 0xe4c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe4bd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x170(%rbp), %rdi
callq 0xa5f0
jmp 0xe4bd
leaq -0x1b8(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x5cd0
movss %xmm1, -0x454(%rbp)
movaps %xmm0, -0x450(%rbp)
jmp 0xe0b4
movss -0x454(%rbp), %xmm0
movaps -0x450(%rbp), %xmm1
movlpd %xmm1, -0x2e0(%rbp)
movss %xmm0, -0x2d8(%rbp)
movl -0x2d8(%rbp), %eax
movl %eax, -0x2c8(%rbp)
movq -0x2e0(%rbp), %rax
movq %rax, -0x2d0(%rbp)
leaq -0x1c4(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x5cd0
movss %xmm1, -0x474(%rbp)
movaps %xmm0, -0x470(%rbp)
jmp 0xe111
movss -0x474(%rbp), %xmm0
movaps -0x470(%rbp), %xmm1
movlpd %xmm1, -0x300(%rbp)
movss %xmm0, -0x2f8(%rbp)
movl -0x2f8(%rbp), %eax
movl %eax, -0x2e8(%rbp)
movq -0x300(%rbp), %rax
movq %rax, -0x2f0(%rbp)
leaq -0x2d0(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
callq 0x5db0
movss %xmm1, -0x494(%rbp)
movaps %xmm0, -0x490(%rbp)
jmp 0xe16e
movss -0x494(%rbp), %xmm0
movaps -0x490(%rbp), %xmm1
movlpd %xmm1, -0x310(%rbp)
movss %xmm0, -0x308(%rbp)
movl -0x308(%rbp), %eax
movl %eax, -0x2b8(%rbp)
movq -0x310(%rbp), %rax
movq %rax, -0x2c0(%rbp)
leaq -0x2c0(%rbp), %rdi
movss 0xe4e(%rip), %xmm0      # 0xf004
callq 0x5d40
jmp 0xe1bd
leaq 0x8058(%rip), %rsi      # 0x1621c
leaq -0x2c0(%rbp), %rdi
callq 0xe940
movss %xmm0, -0x498(%rbp)
jmp 0xe1da
movss -0x498(%rbp), %xmm0
movss %xmm0, -0x314(%rbp)
testb $0x1, -0x9(%rbp)
je 0xe2e9
leaq -0x200(%rbp), %rax
movq %rax, -0x4a8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x4a0(%rbp)
movss -0x314(%rbp), %xmm0
leaq -0x320(%rbp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm1
callq 0x5c00
jmp 0xe229
movq -0x4a0(%rbp), %rsi
movq -0x4a8(%rbp), %rdi
movl -0x318(%rbp), %eax
movl %eax, -0x328(%rbp)
movq -0x320(%rbp), %rax
movq %rax, -0x330(%rbp)
movsd -0x330(%rbp), %xmm0
movss -0x328(%rbp), %xmm1
leaq -0x70(%rbp), %rdx
callq 0xd570
jmp 0xe26c
leaq -0x230(%rbp), %rax
movq %rax, -0x4b8(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x4b0(%rbp)
movss -0x314(%rbp), %xmm2
leaq -0x33c(%rbp), %rdi
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x5c00
jmp 0xe2a1
movq -0x4b0(%rbp), %rsi
movq -0x4b8(%rbp), %rdi
movl -0x334(%rbp), %eax
movl %eax, -0x348(%rbp)
movq -0x33c(%rbp), %rax
movq %rax, -0x350(%rbp)
movsd -0x350(%rbp), %xmm0
movss -0x348(%rbp), %xmm1
leaq -0xa0(%rbp), %rdx
callq 0xd570
jmp 0xe2e7
jmp 0xe363
leaq -0x1a0(%rbp), %rax
movq %rax, -0x4c8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x4c0(%rbp)
movss -0x314(%rbp), %xmm2
leaq -0x35c(%rbp), %rdi
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x5c00
jmp 0xe31e
movq -0x4c0(%rbp), %rsi
movq -0x4c8(%rbp), %rdi
movl -0x354(%rbp), %eax
movl %eax, -0x368(%rbp)
movq -0x35c(%rbp), %rax
movq %rax, -0x370(%rbp)
movsd -0x370(%rbp), %xmm0
movss -0x368(%rbp), %xmm1
leaq -0x50(%rbp), %rdx
callq 0xd570
jmp 0xe361
jmp 0xe363
leaq -0x170(%rbp), %rdi
callq 0xa5f0
movl -0x154(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x154(%rbp)
jmp 0xdc92
testb $0x1, -0x9(%rbp)
je 0xe3df
leaq -0x390(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
callq 0x6cc0
jmp 0xe3a2
leaq -0x50(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0xe990
jmp 0xe3b4
leaq -0x390(%rbp), %rdi
callq 0x65e0
jmp 0xe3df
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x390(%rbp), %rdi
callq 0x65e0
jmp 0xe4bd
movq 0x7bf2(%rip), %rdi      # 0x15fd8
leaq 0xe25(%rip), %rsi       # 0xf212
callq 0x21f0
movq %rax, -0x4d0(%rbp)
jmp 0xe3fb
movq -0x4d0(%rbp), %rdi
movq 0x7bbf(%rip), %rsi      # 0x15fc8
callq 0x2220
jmp 0xe410
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
callq 0x6a80
jmp 0xe41d
movq 0x7bb4(%rip), %rdi      # 0x15fd8
leaq 0xdfa(%rip), %rsi       # 0xf225
callq 0x21f0
movq %rax, -0x4d8(%rbp)
jmp 0xe439
movq -0x4d8(%rbp), %rdi
movq 0x7b81(%rip), %rsi      # 0x15fc8
callq 0x2220
jmp 0xe44e
leaq -0x50(%rbp), %rdi
callq 0x6640
jmp 0xe459
movq 0x7b78(%rip), %rdi      # 0x15fd8
leaq 0xdd0(%rip), %rsi       # 0xf237
callq 0x21f0
movq %rax, -0x4e0(%rbp)
jmp 0xe475
movq -0x4e0(%rbp), %rdi
movq 0x7b45(%rip), %rsi      # 0x15fc8
callq 0x2220
jmp 0xe48a
leaq -0x110(%rbp), %rdi
callq 0xe9d0
leaq -0xa0(%rbp), %rdi
callq 0x65e0
leaq -0x70(%rbp), %rdi
callq 0x65e0
leaq -0x50(%rbp), %rdi
callq 0x65e0
addq $0x4e0, %rsp            # imm = 0x4E0
popq %rbp
retq
leaq -0x110(%rbp), %rdi
callq 0xe9d0
leaq -0xa0(%rbp), %rdi
callq 0x65e0
leaq -0x70(%rbp), %rdi
callq 0x65e0
leaq -0x50(%rbp), %rdi
callq 0x65e0
movq -0x78(%rbp), %rdi
callq 0x2380