瀏覽代碼

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

Juan Linietsky 11 年之前
父節點
當前提交
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;