// Copyright (C) Kimmo Lahtinen - All Rights Reserved

// Common defines and functions, included at the beginning of fragment and vertex shaders

//////////////////////////////////////////////////////////////////
// Platform specific setup

#if defined(PLATFORM_WINDOWS)

// Define the OpenGL ES specific precision modifiers away
#define highp
#define mediump
#define lowp

#elif defined(PLATFORM_MAC)

// Define the OpenGL ES specific precision modifiers away
#define highp
#define mediump
#define lowp

#elif defined(PLATFORM_IOS)

// Note: Instancing extension enabled in all shaders even though none would use it, should probably check
// if it affects anything negatively, but probably not
#extension GL_EXT_draw_instanced : enable
#define gl_InstanceID gl_InstanceIDEXT

// Default precision for types
precision mediump float;
precision mediump int;

#else
#error Unknown platform macro
#endif

//////////////////////////////////////////////////////////////////
// Rendering quality settings

#if defined(QUALITY_MAX)

// Water
#define WATER_PER_PIXEL_DEPTH
#define WATER_ENABLE_FOAM
#define WATER_ENABLE_SPECULAR

// Background plasma / stars / gradient / etc.
#define BG_ENABLE_PLASMA_ANIMATION
#define BG_ENABLE_FANCY_GLOW
#define BG_ENABLE_GRADIENT
#define BG_ENABLE_STARS

// Light with shadows
#define LIGHT_SHADOW_SMOOTH_ANGLE
#define LIGHT_SHADOW_BLUR_RADIAL
#define LIGHT_SHADOW_BLUR_MODE_GAUSSIAN

// Megasprite
#define MEGASPRITE_BETTER_COLOR_FLASHES

#elif defined(QUALITY_MED_STEP_1)
// First step up in quality (better iOS devices etc.)

// Water
#define WATER_ENABLE_FOAM
#define WATER_ENABLE_SPECULAR

// Background plasma / stars / gradient / etc.
#define BG_ENABLE_PLASMA_ANIMATION
#define BG_ENABLE_FANCY_GLOW
#define BG_ENABLE_GRADIENT

// Light with shadows
#define LIGHT_SHADOW_SMOOTH_ANGLE
#define LIGHT_SHADOW_BLUR_RADIAL

// Megasprite
#define MEGASPRITE_BETTER_COLOR_FLASHES

#elif defined(QUALITY_MIN)
// All configurable effects off
#else
#error Unknown quality specifier
#endif

//////////////////////////////////////////////////////////////////
// Bug fix overrides

#if defined(INTEL_OLD_MAC_DRIVER)

#ifdef BG_ENABLE_STARS
#undef BG_ENABLE_STARS
#endif

#endif

//////////////////////////////////////////////////////////////////
// Constants

#define UU_PI		(3.14159265)
#define UU_PI_HALF	(1.57079633)
#define UU_PI_TWO	(6.28318531)
#define UU_SQRT_TWO (1.41421356)

//////////////////////////////////////////////////////////////////
// Camera transforms
// Note/TODO: to_clip_space would maybe be better name

uniform highp mat3 uni_view_transform_2d;

highp vec4 to_screen_pos_2d(highp vec2 pos_world)
{
	highp vec2 pos_screen = (uni_view_transform_2d * vec3(pos_world, 1.0)).xy;
	return vec4(pos_screen.x, pos_screen.y, 0.0, 1.0);
}

uniform highp mat4 uni_mtx_view_project; // World to view + project

highp vec4 to_screen_pos_3d(highp vec3 pos_world)
{
	return uni_mtx_view_project * vec4(pos_world, 1.0);
}

//////////////////////////////////////////////////////////////////
// Basic lighting calculation

uniform highp vec3 uni_ambient_color;
uniform highp vec3 uni_directional_dir;
uniform highp vec3 uni_directional_color;

vec3 light_surface(vec3 surface_normal)
{
	vec3 directional_color = uni_directional_color * max(0.0, dot(surface_normal, -uni_directional_dir));
	return uni_ambient_color + directional_color;
}

//////////////////////////////////////////////////////////////////
// Gameplay map size parameters

uniform highp vec2 uni_map_size_max;
uniform highp vec2 uni_map_size_current;

//////////////////////////////////////////////////////////////////
// Lightmap

vec2 cutaway_lightmap_uv(vec2 vtx_pos, int texturing_axis)
{
	// uni_map_size_max is lightmap world size currently always, no matter what the real map size is
	vec2 uv = vtx_pos / uni_map_size_max;

	// Adjust the UV a bit invards since we're on the border of lightmap and 
	// it'll bilinearly sample a bit of black otherwise
	float uv_adjust = -0.0005; // TODO: should probably be lightmap resolution dependent and not adhoc value
	uv[1 - texturing_axis] += uv_adjust;

	return uv;
}

uniform mediump sampler2D uni_texture_level_lightmap;

// Color scaling back to real scale
#define LIGHTMAP_COLOR_SCALE (2.0)

// Color range when writing to lightmap
#define LIGHTMAP_COLOR_WRITE_FACTOR (0.5)

vec3 sample_level_lightmap(vec2 uv)
{
	return texture2D(uni_texture_level_lightmap, uv).rgb * LIGHTMAP_COLOR_SCALE;
}
