// File: /workspace/github_c_makefile_star2_O2/Nealsbo[P]C-Software-Renderer/src/shader.c
// Function: Shader_Fragment
color_t Shader_Fragment( shader_t *s, obj_model_t *model, vec3 bary ) {
	vec3 fragPos, normal, ambient, diffuse, light_dir, view_dir, refl_dir, specular, res;
	vec2 uv;
	float diff, spec;
	//vec2 uv      = vec4_toVec2( vec4_byMat4( vec3_toVec4( bary ), s->var_uv ) );
	uv      = vec2_create( bary.x*s->uvs[0].x + bary.y*s->uvs[1].x + bary.z*s->uvs[2].x,
						   bary.x*s->uvs[0].y + bary.y*s->uvs[1].y + bary.z*s->uvs[2].y );
                                
	if( !s->isLit ) {
		return Bitmap_GetPixelUV( model->diffmap->bitmap, uv );
	}
	
	float ambientStr = 0.1f, specularStr = 1.0f;
	//vec3 fragPos = vec3_nrm( vec3_byMat4( bary, s->var_pos ) );
	//vec3 normal  = vec3_nrm( vec3_byMat4( bary , s->var_nrm ) );
	fragPos = vec3_nrm( vec3_create( bary.x*s->pos[0].x + bary.y*s->pos[1].x + bary.z*s->pos[2].x,
									 bary.x*s->pos[0].y + bary.y*s->pos[1].y + bary.z*s->pos[2].y,
									 bary.x*s->pos[0].z + bary.y*s->pos[1].z + bary.z*s->pos[2].z ) );
                                          
	normal  = vec3_nrm( vec3_create( bary.x*s->normals[0].x + bary.y*s->normals[1].x + bary.z*s->normals[2].x + s->normals[3].x,
									 bary.x*s->normals[0].y + bary.y*s->normals[1].y + bary.z*s->normals[2].y + s->normals[3].y,
									 bary.x*s->normals[0].z + bary.y*s->normals[1].z + bary.z*s->normals[2].z + s->normals[3].z) );
	
	if( model->normalmap != NULL ) {
		vec3 texN = vec3_sub( vec3_mlt( Color_ToVec3( Bitmap_GetPixelUV( model->normalmap->bitmap, uv ) ), 2.0f ), vec3_create( 1.0f, 1.0f, 1.0f ) ); // normal * 2 - 1
		if( s->isNormalInverted ) // if required to invert normal map
			normal = vec3_nrm( vec3_add( vec3_create( -texN.x, -texN.y, texN.z ), normal ) );
		else
			normal = vec3_nrm( vec3_add( texN, normal ) );
	}

	// ambient light
	ambient    = vec3_mlt( s->ambient_color, ambientStr );
	
	// diffuse light
	light_dir = vec3_nrm( vec3_sub( s->light_pos, fragPos ) );
	diff      = MAX( vec3_dot( normal, light_dir ), 0.0f );
	diffuse   = vec3_mlt( s->light_color, diff );
	
	// specular light
	view_dir  = vec3_nrm( vec3_sub( s->cam_pos, fragPos ) );
	refl_dir  = vec3_nrm( vec3_refl( vec3_neg( light_dir ), normal ) );
	spec      = powf( MAX( vec3_dot( view_dir, refl_dir ), 0.0f ), 32.0f );
	specular  = vec3_mlt( s->light_color, specularStr * spec );
	
	res       = vec3_add( vec3_add( vec3_mlt( diffuse, 0.5f ), ambient ), specular );
	
	return Color_IntensityVec3( Bitmap_GetPixelUV( model->diffmap->bitmap, uv ), res );
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x98, %rsp
movaps %xmm1, %xmm3
movaps %xmm0, %xmm4
movq %rsi, %rbx
movq %rdi, %r14
movaps %xmm0, %xmm2
shufps $0x55, %xmm0, %xmm2     # xmm2 = xmm2[1,1],xmm0[1,1]
movss 0x1d4(%rdi), %xmm0
mulss %xmm2, %xmm0
movss 0x1cc(%rdi), %xmm1
mulss %xmm4, %xmm1
addss %xmm0, %xmm1
movss 0x1dc(%rdi), %xmm0
mulss %xmm3, %xmm0
addss %xmm1, %xmm0
movss 0x1d8(%rdi), %xmm1
movaps %xmm2, 0x10(%rsp)
mulss %xmm2, %xmm1
movss 0x1d0(%rdi), %xmm2
movaps %xmm4, 0x30(%rsp)
mulss %xmm4, %xmm2
addss %xmm1, %xmm2
movss 0x1e0(%rdi), %xmm1
movss %xmm3, 0x20(%rsp)
mulss %xmm3, %xmm1
addss %xmm2, %xmm1
callq 0x2736
cmpl $0x0, 0x1e8(%r14)
je 0x6585
movaps %xmm0, 0x60(%rsp)
movss 0x110(%r14), %xmm0
movaps 0x10(%rsp), %xmm1
mulss %xmm1, %xmm0
movaps %xmm1, %xmm3
movss 0x100(%r14), %xmm1
movaps 0x30(%rsp), %xmm2
mulss %xmm2, %xmm1
movaps %xmm2, %xmm4
addss %xmm0, %xmm1
movss 0x120(%r14), %xmm0
movss 0x20(%rsp), %xmm2
mulss %xmm2, %xmm0
movaps %xmm2, %xmm5
addss %xmm1, %xmm0
movss 0x114(%r14), %xmm1
mulss %xmm3, %xmm1
movss 0x104(%r14), %xmm2
mulss %xmm4, %xmm2
addss %xmm1, %xmm2
movss 0x124(%r14), %xmm1
mulss %xmm5, %xmm1
addss %xmm2, %xmm1
movss 0x118(%r14), %xmm2
mulss %xmm3, %xmm2
movss 0x108(%r14), %xmm3
mulss %xmm4, %xmm3
addss %xmm2, %xmm3
movss 0x128(%r14), %xmm2
mulss %xmm5, %xmm2
addss %xmm3, %xmm2
callq 0x2911
callq 0x29aa
movaps %xmm0, 0x50(%rsp)
movss %xmm1, 0x8(%rsp)
movss 0x140(%r14), %xmm0
movaps 0x10(%rsp), %xmm2
mulss %xmm2, %xmm0
movss 0x130(%r14), %xmm1
movaps 0x30(%rsp), %xmm5
mulss %xmm5, %xmm1
addss %xmm0, %xmm1
movss 0x150(%r14), %xmm0
movss 0x20(%rsp), %xmm3
mulss %xmm3, %xmm0
addss %xmm1, %xmm0
addss 0x160(%r14), %xmm0
movss 0x144(%r14), %xmm1
mulss %xmm2, %xmm1
movaps %xmm2, %xmm4
movss 0x134(%r14), %xmm2
mulss %xmm5, %xmm2
addss %xmm1, %xmm2
movss 0x154(%r14), %xmm1
mulss %xmm3, %xmm1
addss %xmm2, %xmm1
addss 0x164(%r14), %xmm1
mulss 0x148(%r14), %xmm4
movss 0x138(%r14), %xmm2
mulss %xmm5, %xmm2
mulss 0x158(%r14), %xmm3
addss %xmm4, %xmm2
addss %xmm2, %xmm3
addss 0x168(%r14), %xmm3
movaps %xmm3, %xmm2
callq 0x2911
callq 0x29aa
movq 0x160(%rbx), %rax
testq %rax, %rax
movss %xmm1, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
je 0x65c4
movq (%rax), %rdi
movaps 0x60(%rsp), %xmm0
callq 0x239d
movl %eax, %edi
callq 0x20f5
movss 0xaf2(%rip), %xmm2      # 0x7010
callq 0x2929
movaps %xmm0, 0x30(%rsp)
movss %xmm1, 0xc(%rsp)
movss 0xade(%rip), %xmm0      # 0x7014
movaps %xmm0, %xmm1
movaps %xmm0, %xmm2
callq 0x2911
movaps %xmm0, %xmm2
movaps %xmm1, %xmm3
movaps 0x30(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x2921
movaps %xmm0, %xmm3
movaps %xmm1, %xmm2
cmpl $0x0, 0x1ec(%r14)
je 0x659e
movaps 0xbe2(%rip), %xmm1      # 0x7150
movaps %xmm3, %xmm0
xorps %xmm1, %xmm0
shufps $0x55, %xmm3, %xmm3     # xmm3 = xmm3[1,1,1,1]
xorps %xmm1, %xmm3
movaps %xmm3, %xmm1
callq 0x2911
jmp 0x65a4
movq 0x158(%rbx), %rax
movq (%rax), %rdi
addq $0x98, %rsp
popq %rbx
popq %r14
jmp 0x239d
movaps %xmm3, %xmm0
movaps %xmm2, %xmm1
movaps 0x10(%rsp), %xmm2
movss 0x20(%rsp), %xmm3
callq 0x2919
callq 0x29aa
movaps %xmm0, 0x10(%rsp)
movss %xmm1, 0x20(%rsp)
movsd 0x19c(%r14), %xmm0
movss 0x1a4(%r14), %xmm1
movss 0x1442(%rip), %xmm2     # 0x7a20
callq 0x2929
movaps %xmm0, 0x80(%rsp)
movss %xmm1, 0x4c(%rsp)
movsd 0x184(%r14), %xmm0
movss 0x18c(%r14), %xmm1
movaps 0x50(%rsp), %xmm2
movss 0x8(%rsp), %xmm3
callq 0x2921
callq 0x29aa
movaps %xmm0, %xmm2
movaps %xmm1, %xmm3
movaps 0x10(%rsp), %xmm0
movss 0x20(%rsp), %xmm1
movaps %xmm2, 0x30(%rsp)
movss %xmm3, 0xc(%rsp)
callq 0x293d
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
xorps %xmm2, %xmm2
jbe 0x6662
movaps 0x10(%rsp), %xmm0
movss 0x20(%rsp), %xmm1
movaps 0x30(%rsp), %xmm2
movss 0xc(%rsp), %xmm3
callq 0x293d
movaps %xmm0, %xmm2
movsd 0x190(%r14), %xmm0
movss 0x198(%r14), %xmm1
callq 0x2929
movaps %xmm0, 0x70(%rsp)
movss %xmm1, 0x48(%rsp)
movsd 0x178(%r14), %xmm0
movss 0x180(%r14), %xmm1
movaps 0x50(%rsp), %xmm2
movss 0x8(%rsp), %xmm3
callq 0x2921
callq 0x29aa
movaps %xmm0, 0x50(%rsp)
movss %xmm1, 0x8(%rsp)
movaps 0x30(%rsp), %xmm0
movss 0xc(%rsp), %xmm1
callq 0x299c
movaps 0x10(%rsp), %xmm2
movss 0x20(%rsp), %xmm3
callq 0x2a13
callq 0x29aa
movaps %xmm0, %xmm2
movaps %xmm1, %xmm3
movaps 0x50(%rsp), %xmm0
movss 0x8(%rsp), %xmm1
movaps %xmm2, 0x20(%rsp)
movss %xmm3, 0x10(%rsp)
callq 0x293d
xorps %xmm2, %xmm2
ucomiss %xmm2, %xmm0
jbe 0x6722
movaps 0x50(%rsp), %xmm0
movss 0x8(%rsp), %xmm1
movaps 0x20(%rsp), %xmm2
movss 0x10(%rsp), %xmm3
callq 0x293d
movaps %xmm0, %xmm2
movss 0x162e(%rip), %xmm1     # 0x7d58
movaps %xmm2, %xmm0
callq 0x1220
movaps %xmm0, %xmm2
movsd 0x190(%r14), %xmm0
movss 0x198(%r14), %xmm1
callq 0x2929
movaps %xmm0, 0x20(%rsp)
movss %xmm1, 0x10(%rsp)
movss 0x8cd(%rip), %xmm2      # 0x702c
movaps 0x70(%rsp), %xmm0
movss 0x48(%rsp), %xmm1
callq 0x2929
movaps 0x80(%rsp), %xmm2
movss 0x4c(%rsp), %xmm3
callq 0x2919
movaps 0x20(%rsp), %xmm2
movss 0x10(%rsp), %xmm3
callq 0x2919
movaps %xmm0, 0x20(%rsp)
movss %xmm1, 0x10(%rsp)
movq 0x158(%rbx), %rax
movq (%rax), %rdi
movaps 0x60(%rsp), %xmm0
callq 0x239d
movl %eax, %edi
movaps 0x20(%rsp), %xmm0
movss 0x10(%rsp), %xmm1
addq $0x98, %rsp
popq %rbx
popq %r14
jmp 0x200c