Sfoglia il codice sorgente

missing fils from yesterday comit.
must have made some mistake with git,
not sure why they were not sent..

Juan Linietsky 11 anni fa
parent
commit
af4a97bef9

+ 20 - 0
core/image.cpp

@@ -1998,6 +1998,26 @@ void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) {
 
 
 
+void Image::normalmap_to_xy() {
+
+	convert(Image::FORMAT_RGBA);
+
+	{
+		int len = data.size()/4;
+		DVector<uint8_t>::Write wp = data.write();
+		unsigned char *data_ptr=wp.ptr();
+
+		for(int i=0;i<len;i++) {
+
+			data_ptr[(i<<2)+3]=data_ptr[(i<<2)+0]; //x to w
+			data_ptr[(i<<2)+0]=data_ptr[(i<<2)+1]; //y to xz
+			data_ptr[(i<<2)+2]=data_ptr[(i<<2)+1];
+		}
+	}
+
+	convert(Image::FORMAT_GRAYSCALE_ALPHA);
+}
+
 void Image::srgb_to_linear() {
 
 	if (data.size()==0)

+ 1 - 0
core/image.h

@@ -333,6 +333,7 @@ public:
 	void fix_alpha_edges();
 	void premultiply_alpha();
 	void srgb_to_linear();
+	void normalmap_to_xy();
 
 	void blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2& p_dest);
 	void brush_transfer(const Image& p_src, const Image& p_brush, const Point2& p_dest);

+ 110 - 32
drivers/gles2/rasterizer_gles2.cpp

@@ -63,6 +63,13 @@
 #define _glClearDepth glClearDepthf
 #endif
 
+
+#define _GL_SRGB_EXT 0x8C40
+#define _GL_SRGB_ALPHA_EXT 0x8C42
+
+#define _GL_TEXTURE_MAX_ANISOTROPY_EXT          0x84FE
+#define _GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT      0x84FF
+
 //#define DEBUG_OPENGL
 
 #ifdef DEBUG_OPENGL
@@ -303,9 +310,23 @@ void RasterizerGLES2::_draw_primitive(int p_points, const Vector3 *p_vertices, c
 #define _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG                   0x8C01
 #define _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                  0x8C02
 #define _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                  0x8C03
+
+#define _EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT               0x8A54
+#define _EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT               0x8A55
+#define _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT         0x8A56
+#define _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT         0x8A57
+
+
 #define _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
 #define _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
 #define _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+
+#define _EXT_COMPRESSED_LUMINANCE_LATC1_EXT                 0x8C70
+#define _EXT_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT          0x8C71
+#define _EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT           0x8C72
+#define _EXT_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT    0x8C73
+
+
 #define _EXT_COMPRESSED_RED_RGTC1_EXT 0x8DBB
 #define _EXT_COMPRESSED_RED_RGTC1 0x8DBB
 #define _EXT_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
@@ -316,6 +337,22 @@ void RasterizerGLES2::_draw_primitive(int p_points, const Vector3 *p_vertices, c
 #define _EXT_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
 #define _EXT_ETC1_RGB8_OES           0x8D64
 
+
+
+#define _EXT_SLUMINANCE_NV                                  0x8C46
+#define _EXT_SLUMINANCE_ALPHA_NV                            0x8C44
+#define _EXT_SRGB8_NV                                       0x8C41
+#define _EXT_SLUMINANCE8_NV                                 0x8C47
+#define _EXT_SLUMINANCE8_ALPHA8_NV                          0x8C45
+
+
+#define _EXT_COMPRESSED_SRGB_S3TC_DXT1_NV                   0x8C4C
+#define _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV             0x8C4D
+#define _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV             0x8C4E
+#define _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV             0x8C4F
+
+
+
 #define _EXT_ATC_RGB_AMD                        0x8C92
 #define _EXT_ATC_RGBA_EXPLICIT_ALPHA_AMD        0x8C93
 #define _EXT_ATC_RGBA_INTERPOLATED_ALPHA_AMD    0x87EE
@@ -333,7 +370,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 
 		case Image::FORMAT_GRAYSCALE: {
 			r_gl_components=1;
-			r_gl_format=GL_LUMINANCE;
+			r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_NV:GL_LUMINANCE;
 
 		} break;
 		case Image::FORMAT_INTENSITY: {
@@ -341,14 +378,14 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 			if (!image.empty())
 				image.convert(Image::FORMAT_RGBA);
 			r_gl_components=4;
-			r_gl_format=GL_RGBA;
+			r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 			r_has_alpha_cache=true;
 		} break;
 		case Image::FORMAT_GRAYSCALE_ALPHA: {
 
 			//image.convert(Image::FORMAT_RGBA);
 			r_gl_components=2;
-			r_gl_format=GL_LUMINANCE_ALPHA;
+			r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_ALPHA_NV:GL_LUMINANCE_ALPHA;
 			r_has_alpha_cache=true;
 		} break;
 
@@ -357,7 +394,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 			if (!image.empty())
 				image.convert(Image::FORMAT_RGB);
 			r_gl_components=3;
-			r_gl_format=GL_RGB;
+			r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_EXT:GL_RGB;
 
 		} break;
 
@@ -366,54 +403,55 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 			if (!image.empty())
 				image.convert(Image::FORMAT_RGBA);
 			r_gl_components=4;
-			r_gl_format=GL_RGBA;
+			r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 			r_has_alpha_cache=true;
 
 		} break;
 		case Image::FORMAT_RGB: {
 
 			r_gl_components=3;
-			r_gl_format=GL_RGB;
+			r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_EXT:GL_RGB;
 		} break;
 		case Image::FORMAT_RGBA: {
 
 			r_gl_components=4;
-			r_gl_format=GL_RGBA;
+			r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 			r_has_alpha_cache=true;
 		} break;
 		case Image::FORMAT_BC1: {
 
-			if (!s3tc_supported) {
+			if (!s3tc_supported || (!s3tc_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
 
 				if (!image.empty()) {
 					image.decompress();
 				}
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 
 			} else {
 
 				r_gl_components=1; //doesn't matter much
-				r_gl_format=_EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
 				r_compressed=true;
 			};
 
 		} break;
 		case Image::FORMAT_BC2: {
 
-			if (!s3tc_supported) {
+			if (!s3tc_supported || (!s3tc_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
 
 				if (!image.empty()) {
 					image.decompress();
 				}
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 
 			} else {
 				r_gl_components=1; //doesn't matter much
-				r_gl_format=_EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+
 				r_has_alpha_cache=true;
 				r_compressed=true;
 			};
@@ -421,18 +459,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 		} break;
 		case Image::FORMAT_BC3: {
 
-			if (!s3tc_supported) {
+			if (!s3tc_supported || (!s3tc_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
 
 				if (!image.empty()) {
 					image.decompress();
 				}
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 
 			} else {
 				r_gl_components=1; //doesn't matter much
-				r_gl_format=_EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
 				r_has_alpha_cache=true;
 				r_compressed=true;
 			};
@@ -440,18 +478,18 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 		} break;
 		case Image::FORMAT_BC4: {
 
-			if (!s3tc_supported) {
+			if (!latc_supported) {
 
 				if (!image.empty()) {
 					image.decompress();
 				}
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 
 			} else {
 
-				r_gl_format=_EXT_COMPRESSED_RED_RGTC1;
+				r_gl_format=_EXT_COMPRESSED_LUMINANCE_LATC1_EXT;
 				r_gl_components=1; //doesn't matter much
 				r_compressed=true;
 			};
@@ -459,36 +497,36 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 		} break;
 		case Image::FORMAT_BC5: {
 
-			if (!s3tc_supported) {
+			if (!latc_supported ) {
 
 				if (!image.empty()) {
 					image.decompress();
 				}
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 
 			} else {
-				r_gl_format=_EXT_COMPRESSED_RG_RGTC2;
+				r_gl_format=_EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
 				r_gl_components=1; //doesn't matter much
 				r_compressed=true;
 			};
 		} break;
 		case Image::FORMAT_PVRTC2: {
 
-			if (!pvr_supported) {
+			if (!pvr_supported || (!pvr_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
 
 				if (!image.empty()) {
 					image.decompress();
 				}
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 
 
 			} else {
 
-				r_gl_format=_EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:_EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
 				r_gl_components=1; //doesn't matter much
 				r_compressed=true;
 
@@ -497,18 +535,19 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 		} break;
 		case Image::FORMAT_PVRTC2_ALPHA: {
 
-			if (!pvr_supported) {
+			if (!pvr_supported || (!pvr_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
 
 				if (!image.empty())
 					image.decompress();
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 
 
 			} else {
 
 				r_gl_format=_EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:_EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
 				r_gl_components=1; //doesn't matter much
 				r_compressed=true;
 
@@ -517,16 +556,16 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 		} break;
 		case Image::FORMAT_PVRTC4: {
 
-			if (!pvr_supported) {
+			if (!pvr_supported || (!pvr_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
 
 				if (!image.empty())
 					image.decompress();
 				r_gl_components=4;
-				r_gl_format=GL_RGBA;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
 				r_has_alpha_cache=true;
 			} else {
 
-				r_gl_format=_EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:_EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
 				r_gl_components=1; //doesn't matter much
 				r_compressed=true;
 			}
@@ -534,7 +573,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 		} break;
 		case Image::FORMAT_PVRTC4_ALPHA: {
 
-			if (!pvr_supported) {
+			if (!pvr_supported  || (!pvr_srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
 
 				if (!image.empty())
 					image.decompress();
@@ -543,7 +582,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
 				r_has_alpha_cache=true;
 
 			} else {
-				r_gl_format=_EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
+				r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:_EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
 				r_gl_components=1; //doesn't matter much
 				r_compressed=true;
 			}
@@ -800,6 +839,16 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
 		glTexParameterf( texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
 	}
 
+	if (use_anisotropic_filter) {
+
+		if (texture->flags&VS::TEXTURE_FLAG_ANISOTROPIC_FILTER) {
+
+			glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_level);
+		} else {
+			glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
+		}
+	}
+
 	int mipmaps= (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && img.get_mipmaps()>0) ? img.get_mipmaps() +1 : 1;
 
 
@@ -1047,6 +1096,16 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) {
 	}
 
 
+	if (use_anisotropic_filter) {
+
+		if (texture->flags&VS::TEXTURE_FLAG_ANISOTROPIC_FILTER) {
+
+			glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_level);
+		} else {
+			glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
+		}
+	}
+
 	if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps)
 		glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,use_fast_texture_filter?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR_MIPMAP_LINEAR);
 	else
@@ -8617,6 +8676,12 @@ void RasterizerGLES2::init() {
 	use_texture_instancing=false;
 	use_attribute_instancing=true;
 	full_float_fb_supported=true;
+	srgb_supported=true;
+	latc_supported=true;
+	s3tc_srgb_supported=true;
+	use_anisotropic_filter=true;
+	glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level);
+	anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0)));
 #ifdef OSX_ENABLED
 	use_rgba_shadowmaps=true;
 	use_fp16_fb=false;
@@ -8636,12 +8701,25 @@ void RasterizerGLES2::init() {
 		use_rgba_shadowmaps=true; //no other way, go back to rgba
 	}
 	pvr_supported=extensions.has("GL_IMG_texture_compression_pvrtc");
+	pvr_srgb_supported=extensions.has("GL_EXT_pvrtc_sRGB");
 	etc_supported=extensions.has("GL_OES_compressed_ETC1_RGB8_texture");
 	use_depth24 = extensions.has("GL_OES_depth24");
 	s3tc_supported = extensions.has("GL_EXT_texture_compression_dxt1") || extensions.has("GL_EXT_texture_compression_s3tc") || extensions.has("WEBGL_compressed_texture_s3tc");
 	use_half_float = extensions.has("GL_OES_vertex_half_float");
 	atitc_supported=extensions.has("GL_AMD_compressed_ATC_texture");
 
+
+	srgb_supported=extensions.has("GL_EXT_sRGB");
+	s3tc_srgb_supported =  s3tc_supported && extensions.has("GL_EXT_texture_compression_s3tc");
+	latc_supported = extensions.has("GL_EXT_texture_compression_latc");
+	anisotropic_level=1.0;
+	use_anisotropic_filter=extensions.has("GL_EXT_texture_filter_anisotropic");
+	if (use_anisotropic_filter) {
+		glGetFloatv(_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level);
+		anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0)));
+	}
+
+
 	print_line("S3TC: "+itos(s3tc_supported)+" ATITC: "+itos(atitc_supported));
 
 	GLint vtf;

+ 7 - 0
drivers/gles2/rasterizer_gles2.h

@@ -73,7 +73,10 @@ class RasterizerGLES2 : public Rasterizer {
 	uint8_t *skinned_buffer;
 	int skinned_buffer_size;
 	bool pvr_supported;
+	bool pvr_srgb_supported;
 	bool s3tc_supported;
+	bool s3tc_srgb_supported;
+	bool latc_supported;
 	bool etc_supported;
 	bool atitc_supported;
 	bool npo2_textures_available;
@@ -82,6 +85,8 @@ class RasterizerGLES2 : public Rasterizer {
 	bool full_float_fb_supported;
 	bool use_shadow_mapping;
 	bool use_fp16_fb;
+	bool srgb_supported;
+
 	ShadowFilterTechnique shadow_filter;
 
 	bool use_shadow_esm;
@@ -91,6 +96,8 @@ class RasterizerGLES2 : public Rasterizer {
 	bool use_texture_instancing;
 	bool use_attribute_instancing;
 	bool use_rgba_shadowmaps;
+	bool use_anisotropic_filter;
+	float anisotropic_level;
 
 	bool use_half_float;
 

+ 20 - 0
drivers/gles2/shaders/copy.glsl

@@ -46,6 +46,15 @@ precision mediump int;
 #endif
 
 
+
+float sRGB_gamma_correct(float c){
+    float a = 0.055;
+    if(c < 0.0031308)
+	return 12.92*c;
+    else
+	return (1.0+a)*pow(c, 1.0/2.4) - a;
+}
+
 #define LUM_RANGE 4.0
 
 
@@ -407,15 +416,26 @@ void main() {
 
 #ifdef USE_SRGB
 
+#if 0
+	//this was fast, but was commented out because it looked kind of shitty, might it be fixable?
+
 	{ //i have my doubts about how fast this is
+
 		color.rgb = min(color.rgb,vec3(1.0)); //clamp just in case
 		vec3 S1 = sqrt(color.rgb);
 		vec3 S2 = sqrt(S1);
 		vec3 S3 = sqrt(S2);
 		color.rgb = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.225411470 * color.rgb;
 	}
+#else
+
+	color.r=sRGB_gamma_correct(color.r);
+	color.g=sRGB_gamma_correct(color.g);
+	color.b=sRGB_gamma_correct(color.b);
+
 #endif
 
+#endif
 
 #ifdef USE_HDR_COPY
 

+ 9 - 8
drivers/squish/image_compress_squish.cpp

@@ -18,18 +18,19 @@ void image_compress_squish(Image *p_image) {
 	if (p_image->get_format()>=Image::FORMAT_BC1)
 		return; //do not compress, already compressed
 
-
-	Image::AlphaMode alpha = p_image->detect_alpha();
-	Image::Format target_format;
 	int shift=0;
 	int squish_comp=squish::kColourRangeFit;
-	switch(alpha) {
+	Image::Format target_format;
 
-		case Image::ALPHA_NONE: target_format = Image::FORMAT_BC1; shift=1; squish_comp|=squish::kDxt1; break;
-		case Image::ALPHA_BIT: target_format = Image::FORMAT_BC2; squish_comp|=squish::kDxt3; break;
-		case Image::ALPHA_BLEND: target_format = Image::FORMAT_BC3; squish_comp|=squish::kDxt5; break;
-	}
+	if (p_image->get_format()==Image::FORMAT_GRAYSCALE_ALPHA) {
+		//compressed normalmap
+		target_format = Image::FORMAT_BC3; squish_comp|=squish::kDxt5;;
+	} else if (p_image->detect_alpha()!=Image::ALPHA_NONE) {
 
+		target_format = Image::FORMAT_BC2; squish_comp|=squish::kDxt3;;
+	} else {
+		target_format = Image::FORMAT_BC1; shift=1; squish_comp|=squish::kDxt1;;
+	}
 
 	p_image->convert(Image::FORMAT_RGBA); //always expects rgba
 

+ 11 - 6
scene/2d/physics_body_2d.cpp

@@ -250,7 +250,7 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
 		if (!E) {
 
 			E = contact_monitor->body_map.insert(objid,BodyState());
-			E->get().rc=0;
+//			E->get().rc=0;
 			E->get().in_scene=node && node->is_inside_scene();
 			if (node) {
 				node->connect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene,make_binds(objid));
@@ -260,8 +260,9 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
 				}
 			}
 
+			//E->get().rc++;
 		}
-		E->get().rc++;
+
 		if (node)
 			E->get().shapes.insert(ShapePair(p_body_shape,p_local_shape));
 
@@ -272,24 +273,26 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
 
 	} else {
 
-		E->get().rc--;
+		//E->get().rc--;
 
 		if (node)
 			E->get().shapes.erase(ShapePair(p_body_shape,p_local_shape));
 
-		if (E->get().rc==0) {
+		bool in_scene = E->get().in_scene;
+
+		if (E->get().shapes.empty()) {
 
 			if (node) {
 				node->disconnect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene);
 				node->disconnect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene);
-				if (E->get().in_scene)
+				if (in_scene)
 					emit_signal(SceneStringNames::get_singleton()->body_exit,obj);
 
 			}
 
 			contact_monitor->body_map.erase(E);
 		}
-		if (node && E->get().in_scene) {
+		if (node && in_scene) {
 			emit_signal(SceneStringNames::get_singleton()->body_exit_shape,objid,obj,p_body_shape,p_local_shape);
 		}
 
@@ -381,6 +384,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
 
 		//process remotions
 
+
 		for(int i=0;i<toremove_count;i++) {
 
 			_body_inout(0,toremove[i].body_id,toremove[i].pair.body_shape,toremove[i].pair.local_shape);
@@ -388,6 +392,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
 
 		//process aditions
 
+
 		for(int i=0;i<toadd_count;i++) {
 
 			_body_inout(1,toadd[i].id,toadd[i].shape,toadd[i].local_shape);

+ 1 - 1
scene/2d/physics_body_2d.h

@@ -156,7 +156,7 @@ private:
 	};
 	struct BodyState {
 
-		int rc;
+		//int rc;
 		bool in_scene;
 		VSet<ShapePair> shapes;
 	};

+ 2 - 1
scene/2d/tile_map.cpp

@@ -311,10 +311,11 @@ void TileMap::_recompute_rect_cache() {
 			r_total=r_total.merge(r);
 
 	}
+
 	if (r_total==Rect2()) {
 		rect_cache=Rect2(-10,-10,20,20);
 	} else {
-		rect_cache=r_total;
+		rect_cache=r_total.grow(MAX(cell_size.x,cell_size.y)*quadrant_size);
 	}
 
 	item_rect_changed();

+ 8 - 6
scene/3d/physics_body.cpp

@@ -245,7 +245,7 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape,
 		if (!E) {
 
 			E = contact_monitor->body_map.insert(objid,BodyState());
-			E->get().rc=0;
+			//E->get().rc=0;
 			E->get().in_scene=node && node->is_inside_scene();
 			if (node) {
 				node->connect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene,make_binds(objid));
@@ -256,7 +256,7 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape,
 			}
 
 		}
-		E->get().rc++;
+		//E->get().rc++;
 		if (node)
 			E->get().shapes.insert(ShapePair(p_body_shape,p_local_shape));
 
@@ -267,24 +267,26 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape,
 
 	} else {
 
-		E->get().rc--;
+		//E->get().rc--;
 
 		if (node)
 			E->get().shapes.erase(ShapePair(p_body_shape,p_local_shape));
 
-		if (E->get().rc==0) {
+		bool in_scene = E->get().in_scene;
+
+		if (E->get().shapes.empty()) {
 
 			if (node) {
 				node->disconnect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene);
 				node->disconnect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene);
-				if (E->get().in_scene)
+				if (in_scene)
 					emit_signal(SceneStringNames::get_singleton()->body_exit,obj);
 
 			}
 
 			contact_monitor->body_map.erase(E);
 		}
-		if (node && E->get().in_scene) {
+		if (node && in_scene) {
 			emit_signal(SceneStringNames::get_singleton()->body_exit_shape,objid,obj,p_body_shape,p_local_shape);
 		}
 

+ 1 - 1
scene/3d/physics_body.h

@@ -162,7 +162,7 @@ private:
 	};
 	struct BodyState {
 
-		int rc;
+		//int rc;
 		bool in_scene;
 		VSet<ShapePair> shapes;
 	};

+ 1 - 0
scene/resources/SCsub

@@ -1,6 +1,7 @@
 Import('env')
 
 env.add_source_files(env.scene_sources,"*.cpp")
+env.add_source_files(env.scene_sources,"*.c")
 
 Export('env')
 

+ 6 - 2
scene/resources/material.cpp

@@ -316,14 +316,14 @@ Transform FixedMaterial::get_uv_transform() const {
 
 
 void FixedMaterial::set_fixed_flag(FixedFlag p_flag, bool p_value) {
-	ERR_FAIL_INDEX(p_flag,4);
+	ERR_FAIL_INDEX(p_flag,5);
 	fixed_flags[p_flag]=p_value;
 	VisualServer::get_singleton()->fixed_material_set_flag(material,(VS::FixedMaterialFlags)p_flag,p_value);
 
 }
 
 bool FixedMaterial::get_fixed_flag(FixedFlag p_flag) const {
-	ERR_FAIL_INDEX_V(p_flag,4,false);
+	ERR_FAIL_INDEX_V(p_flag,5,false);
 	return fixed_flags[p_flag];
 }
 
@@ -371,6 +371,7 @@ void FixedMaterial::_bind_methods() {
 	ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_color_array" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_COLOR_ARRAY);
 	ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_point_size" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_POINT_SIZE);
 	ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/discard_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_DISCARD_ALPHA);
+	ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_xy_normalmap" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_XY_NORMALMAP);
 	ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/diffuse" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_DIFFUSE);
 	ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/specular", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR );
 	ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/emission", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_EMISSION );
@@ -431,6 +432,9 @@ FixedMaterial::FixedMaterial() : Material(VS::get_singleton()->fixed_material_cr
 	fixed_flags[FLAG_USE_ALPHA]=false;
 	fixed_flags[FLAG_USE_COLOR_ARRAY]=false;
 	fixed_flags[FLAG_USE_POINT_SIZE]=false;
+	fixed_flags[FLAG_USE_XY_NORMALMAP]=false;
+	fixed_flags[FLAG_DISCARD_ALPHA]=false;
+
 
 	for(int i=0;i<PARAM_MAX;i++) {
 

+ 4 - 2
scene/resources/material.h

@@ -141,7 +141,9 @@ public:
 		FLAG_USE_ALPHA=VS::FIXED_MATERIAL_FLAG_USE_ALPHA,
 		FLAG_USE_COLOR_ARRAY=VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,
 		FLAG_USE_POINT_SIZE=VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE,
-		FLAG_DISCARD_ALPHA=VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA
+		FLAG_DISCARD_ALPHA=VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA,
+		FLAG_USE_XY_NORMALMAP=VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP,
+		FLAG_MAX=VS::FIXED_MATERIAL_FLAG_MAX
 	};
 
 	enum LightShader {
@@ -166,7 +168,7 @@ private:
 	Ref<Texture> texture_param[PARAM_MAX];
 	TexCoordMode texture_texcoord[PARAM_MAX];
 	LightShader light_shader;
-	bool fixed_flags[3];
+	bool fixed_flags[FLAG_MAX];
 	float point_size;
 
 

+ 3 - 1
scene/resources/texture.cpp

@@ -79,6 +79,8 @@ void Texture::_bind_methods() {
 	BIND_CONSTANT( 	FLAG_FILTER );
 	BIND_CONSTANT( FLAG_VIDEO_SURFACE );
 	BIND_CONSTANT( FLAGS_DEFAULT );
+	BIND_CONSTANT( FLAG_ANISOTROPIC_FILTER );
+	BIND_CONSTANT( FLAG_CONVERT_TO_LINEAR );
 
 }
 
@@ -179,7 +181,7 @@ void ImageTexture::_get_property_list( List<PropertyInfo> *p_list) const {
 
 
 
-	p_list->push_back( PropertyInfo( Variant::INT, "flags", PROPERTY_HINT_FLAGS,"Mipmaps,Repeat,Filter") );
+	p_list->push_back( PropertyInfo( Variant::INT, "flags", PROPERTY_HINT_FLAGS,"Mipmaps,Repeat,Filter,Anisotropic,sRGB") );
 	p_list->push_back( PropertyInfo( Variant::IMAGE, "image", img_hint,String::num(lossy_storage_quality)) );
 	p_list->push_back( PropertyInfo( Variant::VECTOR2, "size",PROPERTY_HINT_NONE, ""));
 	p_list->push_back( PropertyInfo( Variant::INT, "storage", PROPERTY_HINT_ENUM,"Uncompressed,Compress Lossy,Compress Lossless"));

+ 2 - 0
scene/resources/texture.h

@@ -52,6 +52,8 @@ public:
 		FLAG_MIPMAPS=VisualServer::TEXTURE_FLAG_MIPMAPS,
 		FLAG_REPEAT=VisualServer::TEXTURE_FLAG_REPEAT,
 		FLAG_FILTER=VisualServer::TEXTURE_FLAG_FILTER,
+		FLAG_ANISOTROPIC_FILTER=VisualServer::TEXTURE_FLAG_ANISOTROPIC_FILTER,
+		FLAG_CONVERT_TO_LINEAR=VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR,
 		FLAG_VIDEO_SURFACE=VisualServer::TEXTURE_FLAG_VIDEO_SURFACE,
 		FLAGS_DEFAULT=FLAG_MIPMAPS|FLAG_REPEAT|FLAG_FILTER,
 	};

+ 9 - 1
servers/physics/body_pair_sw.cpp

@@ -175,7 +175,7 @@ void BodyPairSW::validate_contacts() {
 bool BodyPairSW::setup(float p_step) {
 
 	//cannot collide
-	if (A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC)) {
+	if (A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) {
 		collided=false;
 		return false;
 	}
@@ -267,6 +267,14 @@ bool BodyPairSW::setup(float p_step) {
 			B->add_contact(global_B,c.normal,depth,shape_B,global_A,shape_A,A->get_instance_id(),A->get_self(),crA);
 		}
 
+		if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC)) {
+			c.active=false;
+			collided=false;
+			continue;
+
+		}
+
+
 		c.active=true;
 
 		// Precompute normal mass, tangent mass, and bias.

+ 3 - 2
servers/physics/body_sw.cpp

@@ -196,6 +196,7 @@ void BodySW::set_mode(PhysicsServer::BodyMode p_mode) {
 			_inv_mass=0;
 			_set_static(p_mode==PhysicsServer::BODY_MODE_STATIC);
 			//set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC);
+			set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC && contacts.size());
 			linear_velocity=Vector3();
 			angular_velocity=Vector3();
 		} break;
@@ -460,8 +461,8 @@ void BodySW::integrate_velocities(real_t p_step) {
 	if (mode==PhysicsServer::BODY_MODE_KINEMATIC) {
 
 		_set_transform(new_transform,false);
-		_set_inv_transform(new_transform.affine_inverse());				;
-		if (linear_velocity==Vector3() && angular_velocity==Vector3())
+		_set_inv_transform(new_transform.affine_inverse());
+		if (contacts.size()==0 && linear_velocity==Vector3() && angular_velocity==Vector3())
 			set_active(false); //stopped moving, deactivate
 
 		return;

+ 1 - 1
servers/physics/body_sw.h

@@ -137,7 +137,7 @@ public:
 	_FORCE_INLINE_ void add_area(AreaSW *p_area) { areas.insert(AreaCMP(p_area)); }
 	_FORCE_INLINE_ void remove_area(AreaSW *p_area) { areas.erase(AreaCMP(p_area)); }
 
-	_FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; }
+	_FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; if (mode==PhysicsServer::BODY_MODE_KINEMATIC && p_size) set_active(true);}
 	_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
 
 	_FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); }

+ 5 - 0
servers/physics/collision_object_sw.h

@@ -59,6 +59,9 @@ private:
 		BroadPhaseSW::ID bpid;
 		AABB aabb_cache; //for rayqueries
 		ShapeSW *shape;
+		bool trigger;
+
+		Shape() { trigger=false; }
 	};
 
 	Vector<Shape> shapes;
@@ -125,6 +128,8 @@ public:
 	_FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable=p_enable; }
 	_FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
 
+	_FORCE_INLINE_ void set_shape_as_trigger(int p_idx,bool p_enable) { shapes[p_idx].trigger=p_enable; }
+	_FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; }
 
 	_FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask=p_mask; }
 	_FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }

+ 4 - 3
servers/physics/physics_server_sw.cpp

@@ -540,6 +540,8 @@ void PhysicsServerSW::body_set_shape_as_trigger(RID p_body, int p_shape_idx,bool
 
 	BodySW *body = body_owner.get(p_body);
 	ERR_FAIL_COND(!body);
+	ERR_FAIL_INDEX(p_shape_idx,body->get_shape_count());
+	body->set_shape_as_trigger(p_shape_idx,p_enable);
 
 }
 
@@ -547,10 +549,9 @@ bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx)
 
 	BodySW *body = body_owner.get(p_body);
 	ERR_FAIL_COND_V(!body,false);
+	ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false);
 
-	// todo ?
-
-	return false;
+	body->is_shape_set_as_trigger(p_shape_idx);
 }
 
 

+ 9 - 8
servers/physics_2d/body_2d_sw.cpp

@@ -186,7 +186,7 @@ void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) {
 			_set_inv_transform(get_transform().affine_inverse());
 			_inv_mass=0;
 			_set_static(p_mode==Physics2DServer::BODY_MODE_STATIC);
-			//set_active(p_mode==Physics2DServer::BODY_MODE_KINEMATIC);
+			set_active(p_mode==Physics2DServer::BODY_MODE_KINEMATIC && contacts.size());
 			linear_velocity=Vector2();
 			angular_velocity=0;
 		} break;
@@ -385,10 +385,10 @@ void Body2DSW::integrate_forces(real_t p_step) {
 		motion = new_transform.elements[2] - get_transform().elements[2];
 		do_motion=true;
 
-		for(int i=0;i<get_shape_count();i++) {
-			set_shape_kinematic_advance(i,Vector2());
-			set_shape_kinematic_retreat(i,0);
-		}
+		//for(int i=0;i<get_shape_count();i++) {
+		//	set_shape_kinematic_advance(i,Vector2());
+		//	set_shape_kinematic_retreat(i,0);
+		//}
 
 	} else {
 		if (!omit_force_integration) {
@@ -434,7 +434,7 @@ void Body2DSW::integrate_forces(real_t p_step) {
 	}
 
 	current_area=NULL; // clear the area, so it is set in the next frame
-	contact_count=0;
+	contact_count=0;	
 
 }
 
@@ -449,8 +449,8 @@ void Body2DSW::integrate_velocities(real_t p_step) {
 	if (mode==Physics2DServer::BODY_MODE_KINEMATIC) {
 
 		_set_transform(new_transform,false);
-		_set_inv_transform(new_transform.affine_inverse());				;
-		if (linear_velocity==Vector2() && angular_velocity==0)
+		_set_inv_transform(new_transform.affine_inverse());
+		if (contacts.size()==0 && linear_velocity==Vector2() && angular_velocity==0)
 			set_active(false); //stopped moving, deactivate
 		return;
 	}
@@ -507,6 +507,7 @@ void Body2DSW::call_queries() {
 		Variant v=dbs;
 		const Variant *vp[2]={&v,&fi_callback->callback_udata};
 
+
 		Object *obj = ObjectDB::get_instance(fi_callback->id);
 		if (!obj) {
 

+ 2 - 1
servers/physics_2d/body_2d_sw.h

@@ -134,7 +134,8 @@ public:
 	_FORCE_INLINE_ void add_area(Area2DSW *p_area) { areas.insert(AreaCMP(p_area)); }
 	_FORCE_INLINE_ void remove_area(Area2DSW *p_area) { areas.erase(AreaCMP(p_area)); }
 
-	_FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; }
+	_FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; if (mode==Physics2DServer::BODY_MODE_KINEMATIC && p_size) set_active(true);}
+
 	_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
 
 	_FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); }

+ 5 - 2
servers/physics_2d/body_pair_2d_sw.cpp

@@ -234,7 +234,7 @@ bool BodyPair2DSW::setup(float p_step) {
 
 
 	//cannot collide
-	if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) {
+	if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) {
 		collided=false;
 		return false;
 	}
@@ -343,9 +343,11 @@ bool BodyPair2DSW::setup(float p_step) {
 			}
 		}
 
-		if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B)) {
+		if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) {
 			c.active=false;
 			collided=false;
+			continue;
+
 		}
 
 		// Precompute normal mass, tangent mass, and bias.
@@ -476,6 +478,7 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A,Body2DSW *p_B, int p_sha
 
 BodyPair2DSW::~BodyPair2DSW() {
 
+
 	A->remove_constraint(this);
 	B->remove_constraint(this);
 

+ 1 - 9
servers/physics_2d/collision_object_2d_sw.h

@@ -55,10 +55,8 @@ private:
 		BroadPhase2DSW::ID bpid;
 		Rect2 aabb_cache; //for rayqueries
 		Shape2DSW *shape;
-		Vector2 kinematic_advance;
-		float kinematic_retreat;
 		bool trigger;
-		Shape() { trigger=false; kinematic_retreat=0; }
+		Shape() { trigger=false; }
 	};
 
 	Vector<Shape> shapes;
@@ -105,12 +103,6 @@ public:
 	_FORCE_INLINE_ const Matrix32& get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; }
 	_FORCE_INLINE_ const Rect2& get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; }
 
-	_FORCE_INLINE_ void set_shape_kinematic_advance(int p_index,const Vector2& p_advance) { shapes[p_index].kinematic_advance=p_advance; }
-	_FORCE_INLINE_ Vector2 get_shape_kinematic_advance(int p_index) const { return shapes[p_index].kinematic_advance; }
-
-	_FORCE_INLINE_ void set_shape_kinematic_retreat(int p_index,float p_retreat) { shapes[p_index].kinematic_retreat=p_retreat; }
-	_FORCE_INLINE_ float get_shape_kinematic_retreat(int p_index) const { return shapes[p_index].kinematic_retreat; }
-
 	_FORCE_INLINE_ Matrix32 get_transform() const { return transform; }
 	_FORCE_INLINE_ Matrix32 get_inv_transform() const { return inv_transform; }
 	_FORCE_INLINE_ Space2DSW* get_space() const { return space; }

+ 11 - 1
servers/visual/rasterizer.cpp

@@ -96,7 +96,12 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) {
 		} else {
 			uv_str=_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_NORMAL);
 		}
-		scode+="vec3 normal=tex( fmp_normal_tex,"+uv_str+").xyz * vec3(2.0,2.0,1.0) - vec3(1.0,1.0,0.0);\n";
+		if (p_key.use_xy_normalmap) {
+			scode+="vec2 ywnormal=tex( fmp_normal_tex,"+uv_str+").wy * vec2(2.0,2.0) - vec2(1.0,1.0);\n";
+			scode+="vec3 normal=vec3(ywnormal,sqrt(1 - (ywnormal.x * ywnormal.x) - (ywnormal.y * ywnormal.y) ));\n";
+		} else {
+			scode+="vec3 normal=tex( fmp_normal_tex,"+uv_str+").xyz * vec3(2.0,2.0,1.0) - vec3(1.0,1.0,0.0);\n";
+		}
 		scode+="NORMAL = mix( NORMAL,mat3(TANGENT,BINORMAL,NORMAL) * normal,  fmp_normal);\n";
 		code+=scode;
 	}
@@ -323,6 +328,7 @@ void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedMaterialFlags
 		case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: fm.use_color_array=p_enabled; break;
 		case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: fm.use_pointsize=p_enabled; break;
 		case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: fm.discard_alpha=p_enabled; break;
+		case VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP: fm.use_xy_normalmap=p_enabled; break;
 	}
 
 	if (!fm.dirty_list.in_list())
@@ -341,6 +347,8 @@ bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedMaterialFlags
 		case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: return fm.use_color_array;; break;
 		case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: return fm.use_pointsize;; break;
 		case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: return fm.discard_alpha;; break;
+		case VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP: return fm.use_xy_normalmap;; break;
+
 	}
 
 
@@ -610,6 +618,8 @@ Rasterizer::Rasterizer() {
 	_fixed_material_uv_xform_name="fmp_uv_xform";
 	_fixed_material_point_size_name="fmp_point_size";
 
+	ERR_FAIL_COND( sizeof(FixedMaterialShaderKey)!=4);
+
 }
 
 RID Rasterizer::create_overdraw_debug_material() {

+ 4 - 0
servers/visual/rasterizer.h

@@ -56,6 +56,7 @@ protected:
 			bool use_color_array:1;
 			bool use_pointsize:1;
 			bool discard_alpha:1;
+			bool use_xy_normalmap:1;
 			bool valid:1;
 		};
 
@@ -83,6 +84,7 @@ protected:
 		bool use_color_array;
 		bool discard_alpha;
 		bool use_pointsize;
+		bool use_xy_normalmap;
 		float point_size;
 		Transform uv_xform;
 		VS::FixedMaterialLightShader light_shader;
@@ -102,6 +104,7 @@ protected:
 			k.use_alpha=use_alpha;
 			k.use_color_array=use_color_array;
 			k.use_pointsize=use_pointsize;
+			k.use_xy_normalmap=use_xy_normalmap;
 			k.discard_alpha=discard_alpha;
 			k.light_shader=light_shader;
 			k.valid=true;
@@ -123,6 +126,7 @@ protected:
 			use_color_array=false;
 			use_pointsize=false;
 			discard_alpha=false;
+			use_xy_normalmap=false;
 			point_size=1.0;
 			light_shader=VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT;
 			for(int i=0;i<VS::FIXED_MATERIAL_PARAM_MAX;i++) {

+ 6 - 2
servers/visual_server.h

@@ -87,6 +87,7 @@ public:
 		MAX_PARTICLE_COLOR_PHASES=4,
 		MAX_PARTICLE_ATTRACTORS=4,
 
+
 		MAX_CURSORS = 8,
 	};
 	
@@ -96,8 +97,10 @@ public:
 		TEXTURE_FLAG_MIPMAPS=1, /// Enable automatic mipmap generation - when available
 		TEXTURE_FLAG_REPEAT=2, /// Repeat texture (Tiling), otherwise Clamping
 		TEXTURE_FLAG_FILTER=4, /// Create texure with linear (or available) filter
-		TEXTURE_FLAG_CUBEMAP=8,
-		TEXTURE_FLAG_VIDEO_SURFACE=16,
+		TEXTURE_FLAG_ANISOTROPIC_FILTER=8,
+		TEXTURE_FLAG_CONVERT_TO_LINEAR=16,
+		TEXTURE_FLAG_CUBEMAP=2048,
+		TEXTURE_FLAG_VIDEO_SURFACE=4096,
 		TEXTURE_FLAGS_DEFAULT=TEXTURE_FLAG_REPEAT|TEXTURE_FLAG_MIPMAPS|TEXTURE_FLAG_FILTER
 	};	
 	
@@ -229,6 +232,7 @@ public:
 		FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,
 		FIXED_MATERIAL_FLAG_USE_POINT_SIZE,
 		FIXED_MATERIAL_FLAG_DISCARD_ALPHA,
+		FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP,
 		FIXED_MATERIAL_FLAG_MAX,
 	};
 

+ 28 - 11
tools/editor/io_plugins/editor_scene_import_plugin.cpp

@@ -642,6 +642,7 @@ const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_name
 	{EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,"Materials","Set Alpha in Materials (-alpha)",true},
 	{EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,"Materials","Set Vert. Color in Materials (-vcol)",true},
 	{EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES,"Actions","SRGB->Linear Of Diffuse Textures",false},
+	{EditorSceneImportPlugin::SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY,"Actions","Convert Normal Maps to XY",true},
 	{EditorSceneImportPlugin::SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS,"Actions","Set Material Lightmap to UV2 if Tex2Array Exists",true},
 	{EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,"Create","Create Collisions (-col},-colonly)",true},
 	{EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,"Create","Create Portals (-portal)",true},
@@ -898,7 +899,7 @@ static String _fixstr(const String& p_what,const String& p_str) {
 
 
 
-void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, bool> &image_map) {
+void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, TextureRole> &image_map,int p_flags) {
 
 
 	switch(p_var.get_type()) {
@@ -910,7 +911,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
 
 				if (res->is_type("Texture") && !image_map.has(res)) {
 
-					image_map.insert(res,false);
+					image_map.insert(res,TEXTURE_ROLE_DEFAULT);
 
 
 				} else {
@@ -926,11 +927,22 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
 								Ref<ImageTexture> tex =res->get(E->get().name);
 								if (tex.is_valid()) {
 
-									image_map.insert(tex,true);
+									image_map.insert(tex,TEXTURE_ROLE_DIFFUSE);
 								}
 
+							} else if (E->get().type==Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name=="textures/normal")) {
+
+								Ref<ImageTexture> tex =res->get(E->get().name);
+								if (tex.is_valid()) {
+
+									image_map.insert(tex,TEXTURE_ROLE_NORMALMAP);
+									if (p_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY)
+										res->cast_to<FixedMaterial>()->set_fixed_flag(FixedMaterial::FLAG_USE_XY_NORMALMAP,true);
+								}
+
+
 							} else {
-								_find_resources(res->get(E->get().name),image_map);
+								_find_resources(res->get(E->get().name),image_map,p_flags);
 							}
 						}
 					}
@@ -949,8 +961,8 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
 			for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
 
 
-				_find_resources(E->get(),image_map);
-				_find_resources(d[E->get()],image_map);
+				_find_resources(E->get(),image_map,p_flags);
+				_find_resources(d[E->get()],image_map,p_flags);
 
 			}
 
@@ -961,7 +973,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
 			Array a = p_var;
 			for(int i=0;i<a.size();i++) {
 
-				_find_resources(a[i],image_map);
+				_find_resources(a[i],image_map,p_flags);
 			}
 
 		} break;
@@ -971,7 +983,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag
 }
 
 
-Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map) {
+Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map) {
 
 	// children first..
 	for(int i=0;i<p_node->get_child_count();i++) {
@@ -1002,7 +1014,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
 		for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
 
 			if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) {
-				_find_resources(p_node->get(E->get().name),image_map);
+				_find_resources(p_node->get(E->get().name),image_map,p_flags);
 			}
 		}
 
@@ -1925,7 +1937,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
 
 	Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata);
 
-	Map< Ref<ImageTexture>,bool > imagemap;
+	Map< Ref<ImageTexture>,TextureRole > imagemap;
 
 	scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap);
 
@@ -1971,7 +1983,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
 	int image_flags =  from->get_option("texture_flags");
 	float image_quality = from->get_option("texture_quality");
 
-	for (Map< Ref<ImageTexture>,bool >::Element *E=imagemap.front();E;E=E->next()) {
+	for (Map< Ref<ImageTexture>,TextureRole >::Element *E=imagemap.front();E;E=E->next()) {
 
 		//texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff
 		//but not yet..
@@ -2007,6 +2019,11 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
 			Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
 			print_line("flags: "+itos(image_flags));
 			uint32_t flags = image_flags;
+			if (E->get()==TEXTURE_ROLE_DIFFUSE && scene_flags&SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES)
+				flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR;
+
+			if (E->get()==TEXTURE_ROLE_NORMALMAP && scene_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY)
+				flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_NORMAL_TO_XY;
 
 			imd->set_option("flags",flags);
 			imd->set_option("format",image_format);

+ 9 - 2
tools/editor/io_plugins/editor_scene_import_plugin.h

@@ -100,8 +100,14 @@ class EditorSceneImportPlugin : public EditorImportPlugin {
 
 	Vector<Ref<EditorSceneImporter> > importers;
 
-	void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,bool >& image_map);
-	Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map);
+	enum TextureRole {
+		TEXTURE_ROLE_DEFAULT,
+		TEXTURE_ROLE_DIFFUSE,
+		TEXTURE_ROLE_NORMALMAP
+	};
+
+	void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,TextureRole >& image_map,int p_flags);
+	Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map);
 	void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes);
 	void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes);
 
@@ -133,6 +139,7 @@ public:
 		SCENE_FLAG_GENERATE_TANGENT_ARRAYS=1<<27,
 		SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES=1<<28,
 		SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS=1<<29,
+		SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30,
 	};
 
 

+ 25 - 9
tools/editor/io_plugins/editor_texture_import_plugin.cpp

@@ -46,6 +46,8 @@ static const char *flag_names[]={
 	"Filter (Magnifying)",
 	"Premultiply Alpha",
 	"Convert SRGB->Linear",
+	"Convert NormalMap to XY",
+	"Use Anisotropy",
 	NULL
 };
 
@@ -59,6 +61,8 @@ static const char *flag_short_names[]={
 	"Filter",
 	"PMAlpha",
 	"ToLinear",
+	"ToRG",
+	"Anisoropic",
 	NULL
 };
 
@@ -725,7 +729,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
 	bool atlas = from->get_option("atlas");
 
 	int flags=from->get_option("flags");
-	print_line("GET FLAGS: "+itos(flags));
+
 	uint32_t tex_flags=0;
 
 	if (flags&EditorTextureImportPlugin::IMAGE_FLAG_REPEAT)
@@ -734,6 +738,10 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
 		tex_flags|=Texture::FLAG_FILTER;
 	if (!(flags&EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS))
 		tex_flags|=Texture::FLAG_MIPMAPS;
+	if (flags&EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR)
+		tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR;
+	if (flags&EditorTextureImportPlugin::IMAGE_FLAG_USE_ANISOTROPY)
+		tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER;
 
 	print_line("path: "+p_path+" flags: "+itos(tex_flags));
 	int shrink=1;
@@ -930,11 +938,15 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
 			image.premultiply_alpha();
 		}
 
-		if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) {
-
-			image.srgb_to_linear();
+		if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) {
+			image.normalmap_to_xy();
 		}
 
+		//if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) {
+
+		//	image.srgb_to_linear();
+		//}
+
 		if (shrink>1) {
 
 			int orig_w=image.get_width();
@@ -992,12 +1004,16 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
 			image.premultiply_alpha();
 		}
 
-		if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) {
-
-			print_line("CONVERT BECAUSE: "+itos(flags));
-			image.srgb_to_linear();
+		if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) {
+			image.normalmap_to_xy();
 		}
 
+		//if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) {
+//
+		//	print_line("CONVERT BECAUSE: "+itos(flags));
+		//	image.srgb_to_linear();
+		//}
+
 		int orig_w=image.get_width();
 		int orig_h=image.get_height();
 
@@ -1021,7 +1037,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
 		texture->create_from_image(image,tex_flags);
 
 
-		if (shrink>1) {
+		if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) {
 			texture->set_size_override(Size2(orig_w,orig_h));
 		}
 

+ 3 - 1
tools/editor/io_plugins/editor_texture_import_plugin.h

@@ -93,7 +93,9 @@ public:
 		IMAGE_FLAG_REPEAT=32, //usually disabled in 2D
 		IMAGE_FLAG_FILTER=64, //almost always enabled
 		IMAGE_FLAG_PREMULT_ALPHA=128,//almost always enabled
-		IMAGE_FLAG_CONVERT_TO_LINEAR=256 //convert image to linear
+		IMAGE_FLAG_CONVERT_TO_LINEAR=256, //convert image to linear
+		IMAGE_FLAG_CONVERT_NORMAL_TO_XY=512, //convert image to linear
+		IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear
 	};
 
 	virtual String get_name() const;