Răsfoiți Sursa

Finished the material editor in the IDE. Rewrote screen shader bindings. Fixed depth buffer FBOs and depth buffer binding. Screen shaders now require explicit 'color' and 'depth' rendertarget bindings to access the original scene/screen render. Added an optional precision parameter to String::NumberToString. Numberous resizing improvements to UI controls and IDE props. Added DefaultShaderNoTextureHDR shader to hdr pack. Added a default REMOVE_EVENT Event type. Added Vector2 shader prop. Removed deprecated saving/loading code from Scene. Numerous bugfixes in shader code.

Ivan Safrin 12 ani în urmă
părinte
comite
394f41fca4
43 a modificat fișierele cu 1881 adăugiri și 679 ștergeri
  1. BIN
      Assets/Default asset pack/default.pak
  2. 5 1
      Assets/Default asset pack/default/default.mat
  3. BIN
      Assets/Default asset pack/hdr.pak
  4. 120 0
      Assets/Default asset pack/hdr/DefaultShaderNoTextureHDR.frag
  5. 1 1
      Assets/Default asset pack/hdr/HDRBloomH.frag
  6. 1 1
      Assets/Default asset pack/hdr/HDRBloomV.frag
  7. 9 5
      Assets/Default asset pack/hdr/hdr.mat
  8. 9 5
      Core/Contents/Include/PolyCamera.h
  9. 3 1
      Core/Contents/Include/PolyEvent.h
  10. 1 0
      Core/Contents/Include/PolyGLRenderer.h
  11. 8 0
      Core/Contents/Include/PolyMaterial.h
  12. 1 5
      Core/Contents/Include/PolyRenderer.h
  13. 2 22
      Core/Contents/Include/PolyScene.h
  14. 4 3
      Core/Contents/Include/PolySceneRenderTexture.h
  15. 16 1
      Core/Contents/Include/PolyShader.h
  16. 1 1
      Core/Contents/Include/PolyString.h
  17. 21 32
      Core/Contents/Source/PolyCamera.cpp
  18. 16 16
      Core/Contents/Source/PolyGLRenderer.cpp
  19. 1 1
      Core/Contents/Source/PolyGLSLShader.cpp
  20. 32 23
      Core/Contents/Source/PolyGLSLShaderModule.cpp
  21. 93 2
      Core/Contents/Source/PolyMaterial.cpp
  22. 17 15
      Core/Contents/Source/PolyMaterialManager.cpp
  23. 0 4
      Core/Contents/Source/PolyRenderer.cpp
  24. 0 420
      Core/Contents/Source/PolyScene.cpp
  25. 13 7
      Core/Contents/Source/PolySceneRenderTexture.cpp
  26. 9 6
      Core/Contents/Source/PolyScreen.cpp
  27. 69 6
      Core/Contents/Source/PolyShader.cpp
  28. 3 2
      Core/Contents/Source/PolyString.cpp
  29. 86 5
      IDE/Contents/Include/PolycodeMaterialEditor.h
  30. 124 4
      IDE/Contents/Include/PolycodeProps.h
  31. BIN
      IDE/Contents/Resources/Images/PostPreview/oranges.png
  32. BIN
      IDE/Contents/Resources/Images/new_screenshader.png
  33. BIN
      IDE/Contents/Resources/Images/screenshader_icon.png
  34. 1 1
      IDE/Contents/Source/PolycodeIDEApp.cpp
  35. 560 66
      IDE/Contents/Source/PolycodeMaterialEditor.cpp
  36. 620 20
      IDE/Contents/Source/PolycodeProps.cpp
  37. 4 1
      Modules/Contents/UI/Include/PolyUIButton.h
  38. 2 0
      Modules/Contents/UI/Include/PolyUITextInput.h
  39. 17 2
      Modules/Contents/UI/Source/PolyUIButton.cpp
  40. 1 0
      Modules/Contents/UI/Source/PolyUIElement.cpp
  41. 1 0
      Modules/Contents/UI/Source/PolyUIHSizer.cpp
  42. 7 0
      Modules/Contents/UI/Source/PolyUITextInput.cpp
  43. 3 0
      Modules/Contents/UI/Source/PolyUIVSizer.cpp

BIN
Assets/Default asset pack/default.pak


+ 5 - 1
Assets/Default asset pack/default/default.mat

@@ -36,7 +36,11 @@
 		<shader type="glsl" name="NorColSpec" numAreaLights="4" numSpotLights="2">		
 			<vp source="default/NormalShader.vert"/>
 			<fp source="default/NorColSpec.frag"/>
-		</shader>											
+		</shader>
+		<shader type="glsl" name="PassThrough" screen="true">
+			<vp source="default/ScreenShader.vert"/>
+			<fp source="default/PassThrough.frag"/>
+		</shader>	
 	</shaders>	
 	<materials>
 		<material name="Default">

BIN
Assets/Default asset pack/hdr.pak


+ 120 - 0
Assets/Default asset pack/hdr/DefaultShaderNoTextureHDR.frag

@@ -0,0 +1,120 @@
+varying vec3 normal;
+varying vec4 pos;
+varying vec4 vertexColor;
+
+uniform vec4 diffuse_color;
+uniform vec4 specular_color;
+uniform vec4 ambient_color;
+uniform float shininess;
+
+float calculateAttenuation(in int i, in float dist)
+{
+    return(1.0 / (gl_LightSource[i].constantAttenuation +
+                  gl_LightSource[i].linearAttenuation * dist +
+                  gl_LightSource[i].quadraticAttenuation * dist * dist));
+}
+
+void pointLight(in int i, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular) {
+	vec4 color = diffuse_color;
+	vec4 matspec = specular_color;
+	float shininess = shininess;
+	vec4 lightspec = gl_LightSource[i].specular;
+	vec4 lpos = gl_LightSource[i].position;
+	vec4 s = pos-lpos; 
+	vec4 sn = -normalize(s);
+	
+	vec3 light = sn.xyz;
+	vec3 n = normalize(normal);
+	vec3 r = -reflect(light, n);
+	r = normalize(r);
+	vec3 v = -pos.xyz;
+	v = normalize(v);
+
+	float nDotL = dot(n, sn.xyz);
+	if(nDotL > 0.0) {
+		float dist = length(s);    
+		float attenuation = calculateAttenuation(i, dist);
+
+		diffuse  += color * max(0.0, nDotL) * gl_LightSource[i].diffuse * attenuation;
+
+	  if (shininess != 0.0) {
+    	specular += lightspec * matspec * pow(max(0.0,dot(r, v)), shininess) * attenuation;
+	  }
+	}
+}
+
+
+void spotLight(in int i, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular) {
+	vec4 color = diffuse_color;
+	vec4 matspec = specular_color;
+	float shininess = shininess;
+	vec4 lightspec = gl_LightSource[i].specular;
+	vec4 lpos = gl_LightSource[i].position;
+	vec4 s = pos-lpos; 
+	vec4 sn = -normalize(s);
+
+	vec3 light = sn.xyz;
+	vec3 n = normalize(normal);
+	vec3 r = -reflect(light, n);
+	r = normalize(r);
+	vec3 v = -pos.xyz;
+	v = normalize(v);
+
+	float cos_outer_cone_angle = gl_LightSource[i].spotExponent;
+	float cos_cur_angle = dot(-normalize(gl_LightSource[i].spotDirection), sn.xyz);
+	float cos_inner_cone_angle = gl_LightSource[i].spotCosCutoff;
+
+	float cos_inner_minus_outer_angle = cos_inner_cone_angle - cos_outer_cone_angle;
+	float spot = 0.0;
+	spot = clamp((cos_cur_angle - cos_outer_cone_angle) / cos_inner_minus_outer_angle, 0.0, 1.0);
+	       
+	float nDotL = dot(n, sn.xyz);
+	if(nDotL > 0.0) {
+		float dist = length(s);    
+		float attenuation = calculateAttenuation(i, dist);
+		diffuse  += color * max(0.0, nDotL) * gl_LightSource[i].diffuse * attenuation * spot;
+
+	  if (shininess != 0.0) {
+    	specular += lightspec * matspec * pow(max(0.0,dot(r, v)), shininess) * attenuation * spot;
+	  }
+	}
+}
+
+void doLights(in int numLights, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular) {
+	for (int i = 0; i < numLights; i++) {
+		if (gl_LightSource[i].spotCutoff == 180.0) {
+			pointLight(i, normal, pos, diffuse, specular);
+		} else {
+			spotLight(i, normal, pos, diffuse, specular);
+		}
+    }
+}
+
+
+void main()
+{
+	vec4 diffuse_val  = vec4(0.0);
+	vec4 specular_val = vec4(0.0);
+	doLights(6, normal, pos, diffuse_val, specular_val);
+		
+    vec4 color = (diffuse_val  * vertexColor) +
+                 (specular_val * 1.0)+
+                 (ambient_color * vertexColor);
+
+
+    // fog
+	const float LOG2 = 1.442695;
+	float z = gl_FragCoord.z / gl_FragCoord.w;
+	float fogFactor = exp2( -gl_Fog.density * 
+				   gl_Fog.density * 
+				   z * 
+				   z * 
+				   LOG2 );
+
+	fogFactor = clamp(fogFactor, 0.0, 1.0);
+
+	color = mix(gl_Fog.color, color, fogFactor );    
+	color.a = diffuse_color.a;	
+	gl_FragColor = color;
+
+}

+ 1 - 1
Assets/Default asset pack/hdr/HDRBloomH.frag

@@ -1,5 +1,5 @@
 uniform sampler2D screenTexture;
-const float blurSize = 1.0/512.0;
+uniform float blurSize;
  
 void main(void)
 {

+ 1 - 1
Assets/Default asset pack/hdr/HDRBloomV.frag

@@ -1,5 +1,5 @@
 uniform sampler2D screenTexture;
-const float blurSize = 1.0/512.0;
+uniform float blurSize;
  
 void main(void)
 {

+ 9 - 5
Assets/Default asset pack/hdr/hdr.mat

@@ -4,7 +4,11 @@
 		<shader type="glsl" name="NorColSpecHDR" numAreaLights="4" numSpotLights="2">		
 			<vp source="default/NormalShader.vert"/>
 			<fp source="hdr/NorColSpecHDR.frag"/>
-		</shader>	
+		</shader>
+		<shader type="glsl" name="DefaultShaderNoTextureHDR" numAreaLights="4" numSpotLights="2">	
+			<vp source="default/DefaultShader.vert"/>
+			<fp source="hdr/DefaultShaderNoTextureHDR.frag"/>
+		</shader>		
 		<shader type="glsl" name="HDRProcessShader" screen="true">
 			<vp source="default/ScreenShader.vert"/>
 			<fp source="hdr/HDRProcess.frag"/>
@@ -21,16 +25,16 @@
 			<vp source="default/ScreenShader.vert"/>
 			<fp source="hdr/HDRBloomV.frag"/>
 		</shader>	
-		<shader type="glsl" name="PassThrough" screen="true">
-			<vp source="default/ScreenShader.vert"/>
-			<fp source="default/PassThrough.frag"/>
-		</shader>	
 		<shader type="glsl" name="ExtractBloom" screen="true">
 			<vp source="default/ScreenShader.vert"/>
 			<fp source="hdr/ExtractBloom.frag"/>
 		</shader>							
 	</shaders>
 	<materials>
+		<material name="DefaultHDR" screen="true">
+			<shader name="DefaultShaderNoTextureHDR">
+			</shader>
+		</material>				
 		<material name="HDRProcess" screen="true">
 			<shader name="HDRProcessShader">
 			</shader>

+ 9 - 5
Core/Contents/Include/PolyCamera.h

@@ -121,14 +121,18 @@ namespace Polycode {
 			* @return Current exposure value.
 			*/									
 			Number getExposureLevel();
-			
-			void createPostFilter(Material *shaderMaterial);
-			
+
 			/**
 			* Sets the post-processing shader for the camera.
-			* @param shaderName The shader name of the post-processing filter.
+			* @param shaderMaterial Post processing shader material.
+			*/
+			void setPostFilter(Material *shaderMaterial);
+			
+			/**
+			* Sets the post-processing shader for the camera by name. The material needs have been added as a resource.
+			* @param materialName The material name of the post-processing filter.
 			*/												
-			void setPostFilter(const String& shaderName);
+			void setPostFilterByName(const String& shaderName);
 			
 			/**
 			* Removes the currently assigned post filter.

+ 3 - 1
Core/Contents/Include/PolyEvent.h

@@ -84,7 +84,9 @@ namespace Polycode {
 			static const int NOTIFY_EVENT = EVENTBASE_EVENT+3;
 			static const int FIRE_EVENT = EVENTBASE_EVENT+4;
 			static const int RESOURCE_RELOAD_EVENT = EVENTBASE_EVENT+5;
-									
+			static const int SELECT_EVENT = EVENTBASE_EVENT+6;
+			static const int REMOVE_EVENT = EVENTBASE_EVENT+7;
+															
 			static const int EVENTBASE_NONPOLYCODE = 0x10000;
 		
 			bool deleteOnDispatch;

+ 1 - 0
Core/Contents/Include/PolyGLRenderer.h

@@ -116,6 +116,7 @@ namespace Polycode {
 		void createVertexBufferForMesh(Mesh *mesh);
 		void drawVertexBuffer(VertexBuffer *buffer, bool enableColorBuffer);						
 		void bindFrameBufferTexture(Texture *texture);
+		void bindFrameBufferTextureDepth(Texture *texture);		
 		void unbindFramebuffers();
 		
 		void cullFrontFaces(bool val);

+ 8 - 0
Core/Contents/Include/PolyMaterial.h

@@ -39,11 +39,17 @@ namespace Polycode {
 			virtual ~Material();
 			
 			void addShader(Shader *shader,ShaderBinding *shaderBinding);
+			void addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex);			
 			unsigned int getNumShaders() const;
 			
+			void removeShader(int shaderIndex);
+			
 			void addShaderRenderTarget(ShaderRenderTarget *newTarget);
 			int getNumShaderRenderTargets();
 			ShaderRenderTarget *getShaderRenderTarget(unsigned int index);
+			void removeShaderRenderTarget(int index);
+			void recreateRenderTarget(ShaderRenderTarget *renderTarget);	
+			void recreateRenderTargets();
 			
 			void handleEvent(Event *event);
 						
@@ -62,6 +68,8 @@ namespace Polycode {
 			
 			int blendingMode;
 			
+			bool screenMaterial;
+			
 		protected:
 		
 			std::vector<Shader*> materialShaders;

+ 1 - 5
Core/Contents/Include/PolyRenderer.h

@@ -102,6 +102,7 @@ namespace Polycode {
 		
 		virtual Texture *createFramebufferTexture(unsigned int width, unsigned int height) = 0;
 		virtual void bindFrameBufferTexture(Texture *texture) = 0;
+		virtual void bindFrameBufferTextureDepth(Texture *texture) = 0;
 		virtual void unbindFramebuffers() = 0;
 
 		virtual Image *renderScreenToImage() = 0;
@@ -319,11 +320,6 @@ namespace Polycode {
 		Texture *currentTexture;
 		Material *currentMaterial;
 		
-//		vector<Texture*> shadowMapTextures;
-		
-		Texture *currentFrameBufferTexture;
-		Texture *previousFrameBufferTexture;
-			
 		int textureFilteringMode;
 		int renderMode;
 		

+ 2 - 22
Core/Contents/Include/PolyScene.h

@@ -134,10 +134,6 @@ namespace Polycode {
 		void Render(Camera *targetCamera = NULL);
 		void RenderDepthOnly(Camera *targetCamera);
 		
-		static String readString(OSFILE *inFile);
-		void loadScene(const String& fileName);
-		void generateLightmaps(Number lightMapRes, Number lightMapQuality, int numRadPasses);
-		
 		/**
 		* Adds a light to the scene.
 		* @param light Light to add to the scene.
@@ -151,22 +147,10 @@ namespace Polycode {
 		void removeLight(SceneLight *light);
 		
 		SceneLight *getNearestLight(Vector3 pos);
-		
-		void writeEntityMatrix(SceneEntity *entity, OSFILE *outFile);
-		void writeString(const String& str, OSFILE *outFile);
-		void saveScene(const String& fileName);
-		
-		int getNumStaticGeometry();
-		SceneMesh *getStaticGeometry(int index);
-		
-		virtual void loadCollisionChild(SceneEntity *entity, bool autoCollide=false, int type=0){}
-		
+				
 		int getNumLights();
 		SceneLight *getLight(int index);
-		
-		SceneEntity *getCustomEntityByType(const String& type) const;
-		std::vector<SceneEntity*> getCustomEntitiesByType(const String& type) const;
-		
+				
 		static const unsigned int ENTITY_MESH = 0;
 		static const unsigned int ENTITY_LIGHT = 1;			
 		static const unsigned int ENTITY_CAMERA = 2;			
@@ -208,10 +192,6 @@ namespace Polycode {
 		bool hasLightmaps;
 		
 		std::vector <SceneLight*> lights;
-		std::vector <SceneMesh*> staticGeometry;
-		std::vector <SceneMesh*> collisionGeometry;
-		std::vector <SceneEntity*> customEntities;
-		
 		
 		bool isSceneVirtual;
 		

+ 4 - 3
Core/Contents/Include/PolySceneRenderTexture.h

@@ -44,9 +44,7 @@ namespace Polycode {
 			*/
 			SceneRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight, bool floatingPoint = false);
 			virtual ~SceneRenderTexture();
-			
-			void drawScreen();
-			
+						
 			/**
 			* Returns the actual render texture.
 			*/
@@ -55,6 +53,7 @@ namespace Polycode {
 			Texture *getFilterColorBufferTexture();
 			Texture *getFilterZBufferTexture();			
 
+			void resizeRenderTexture(int newWidth, int newHeight);
 			/**
 			* Returns the target scene.
 			*/			
@@ -70,6 +69,8 @@ namespace Polycode {
 			Texture *filterColorBufferTexture;
 			Texture *filterZBufferTexture;
 		
+			bool floatingPoint;
+		
 			Texture *depthTexture;		
 			Texture *targetTexture;
 			Scene *targetScene;

+ 16 - 1
Core/Contents/Include/PolyShader.h

@@ -108,13 +108,17 @@ namespace Polycode {
 	
 	class _PolyExport ShaderRenderTarget : public PolyBase {
 		public:
+			ShaderRenderTarget();
+			
 			String id;
 			Number width;
 			Number height;
 			int sizeMode;
-			bool hasSize;
 			Texture *texture;
 			
+			Number normalizedWidth;
+			Number normalizedHeight;
+						
 			static const int SIZE_MODE_PIXELS = 0;
 			static const int SIZE_MODE_NORMALIZED = 1;
 	};
@@ -145,6 +149,8 @@ namespace Polycode {
 			Number height;			
 			static const int MODE_IN= 0;
 			static const int MODE_OUT = 1;
+			static const int MODE_COLOR = 2;
+			static const int MODE_DEPTH = 3;			
 	};
 
 	class _PolyExport ShaderBinding : public PolyBase {
@@ -165,6 +171,7 @@ namespace Polycode {
 			LocalShaderParam *getLocalParamByName(const String& name);
 			
 			void addRenderTargetBinding(RenderTargetBinding *binding);
+			void removeRenderTargetBinding(RenderTargetBinding *binding);
 
 			unsigned int getNumRenderTargetBindings();
 			RenderTargetBinding *getRenderTargetBinding(unsigned int index);
@@ -172,6 +179,12 @@ namespace Polycode {
 			unsigned int getNumInTargetBindings();
 			RenderTargetBinding *getInTargetBinding(unsigned int index);
 
+			unsigned int getNumColorTargetBindings();
+			RenderTargetBinding *getColorTargetBinding(unsigned int index);
+
+			unsigned int getNumDepthTargetBindings();
+			RenderTargetBinding *getDepthTargetBinding(unsigned int index);
+
 			unsigned int getNumOutTargetBindings();
 			RenderTargetBinding *getOutTargetBinding(unsigned int index);
 			
@@ -182,6 +195,8 @@ namespace Polycode {
 			std::vector<RenderTargetBinding*> renderTargetBindings;
 			std::vector<RenderTargetBinding*> inTargetBindings;
 			std::vector<RenderTargetBinding*> outTargetBindings;
+			std::vector<RenderTargetBinding*> colorTargetBindings;
+			std::vector<RenderTargetBinding*> depthTargetBindings;			
 	};
 
 }

+ 1 - 1
Core/Contents/Include/PolyString.h

@@ -174,7 +174,7 @@ namespace Polycode {
 			* @param value Number to convert.
 			* @return A string converted from the Number.
 			*/																										
-			static String NumberToString(Number value);
+			static String NumberToString(Number value, int precision = 2);
 
 			/**
 			* Convert an integer to a String.

+ 21 - 32
Core/Contents/Source/PolyCamera.cpp

@@ -262,10 +262,10 @@ void Camera::setParentScene(Scene *parentScene) {
 	this->parentScene = parentScene;
 }
 
-void Camera::setPostFilter(const String& shaderName) {
-	Material *shaderMaterial = (Material*) CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, shaderName);
+void Camera::setPostFilterByName(const String& materialName) {
+	Material *shaderMaterial = (Material*) CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, materialName);
 	if(shaderMaterial)
-		createPostFilter(shaderMaterial);		
+		setPostFilter(shaderMaterial);		
 }
 
 void Camera::removePostFilter() {
@@ -275,32 +275,22 @@ void Camera::removePostFilter() {
 	}
 }
 
-void Camera::createPostFilter(Material *shaderMaterial) {
+void Camera::setPostFilter(Material *shaderMaterial) {
 	if(!shaderMaterial)
 		return;
 	if(shaderMaterial->getNumShaders() == 0)
 		return;
 		
 	this->filterShaderMaterial = shaderMaterial;
-	
-	// TODO: make it save the textures to resource manager and check if they there
-//	originalSceneTexture = CoreServices::getInstance()->getMaterialManager()->createNewTexture(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes());
-//	zBufferSceneTexture = CoreServices::getInstance()->getMaterialManager()->createFramebufferTexture(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes(), 0);
-
 	if(!originalSceneTexture) {
 		CoreServices::getInstance()->getRenderer()->createRenderTextures(&originalSceneTexture, &zBufferSceneTexture, CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes(), shaderMaterial->fp16RenderTargets);
 	}
 	
 	for(int i=0; i < shaderMaterial->getNumShaders(); i++) {
 		ShaderBinding* binding = shaderMaterial->getShader(i)->createBinding();		
-		if(i == 0) {
-			binding->addTexture("screenColorBuffer", originalSceneTexture);
-			binding->addTexture("screenDepthBuffer", zBufferSceneTexture);
-		}
 		localShaderOptions.push_back(binding);
 		binding->addLocalParam("exposure", (void*)&exposureLevel);				
 	}
-	
 
 	_hasFilterShader = true;
 }
@@ -326,37 +316,36 @@ void Camera::drawFilter(Texture *targetTexture, Number targetTextureWidth, Numbe
 	Texture *finalTargetZTexture;	
 		
 	if(targetTexture) {	
-		ShaderBinding* binding = localShaderOptions[0];
-		binding->clearTexture("screenColorBuffer");
-		binding->clearTexture("screenDepthBuffer");				
-		binding->addTexture("screenColorBuffer", targetColorTexture);
-		binding->addTexture("screenDepthBuffer", targetZTexture);
-		
 		finalTargetColorTexture = targetColorTexture;
-		finalTargetZTexture = targetZTexture;
-		
+		finalTargetZTexture = targetZTexture;		
 		CoreServices::getInstance()->getRenderer()->setViewportSize(targetTextureWidth, targetTextureHeight);		
 	} else {
-	
-		ShaderBinding* binding = localShaderOptions[0];
-		binding->clearTexture("screenColorBuffer");
-		binding->clearTexture("screenDepthBuffer");				
-		binding->addTexture("screenColorBuffer", originalSceneTexture);
-		binding->addTexture("screenDepthBuffer", zBufferSceneTexture);	
-	
 		finalTargetColorTexture = originalSceneTexture;
-		finalTargetZTexture = zBufferSceneTexture;
-	
+		finalTargetZTexture = zBufferSceneTexture;	
 		CoreServices::getInstance()->getRenderer()->setViewportSize(CoreServices::getInstance()->getRenderer()->getXRes(), CoreServices::getInstance()->getRenderer()->getYRes());
 	}
 	CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(finalTargetColorTexture);
-//	CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(finalTargetZTexture);	
+	CoreServices::getInstance()->getRenderer()->bindFrameBufferTextureDepth(finalTargetZTexture);
 	parentScene->Render(this);
 	CoreServices::getInstance()->getRenderer()->unbindFramebuffers();
 
+
 	ShaderBinding* materialBinding;		
 	for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
 		materialBinding = filterShaderMaterial->getShaderBinding(i);
+		
+		for(int j=0; j < materialBinding->getNumColorTargetBindings(); j++) {
+			RenderTargetBinding *colorBinding = materialBinding->getColorTargetBinding(j);
+			materialBinding->clearTexture(colorBinding->name);
+			materialBinding->addTexture(colorBinding->name, finalTargetColorTexture);
+		}
+
+		for(int j=0; j < materialBinding->getNumDepthTargetBindings(); j++) {
+			RenderTargetBinding *depthBinding = materialBinding->getDepthTargetBinding(j);
+			materialBinding->clearTexture(depthBinding->name);
+			materialBinding->addTexture(depthBinding->name, finalTargetZTexture);
+		}
+		
 		CoreServices::getInstance()->getRenderer()->applyMaterial(filterShaderMaterial, localShaderOptions[i], i);		
 		if(i==filterShaderMaterial->getNumShaders()-1) {
 				if(targetTexture) {

+ 16 - 16
Core/Contents/Source/PolyGLRenderer.cpp

@@ -579,28 +579,28 @@ void OpenGLRenderer::scale3D(Vector3 *scale) {
 	glScalef(scale->x, scale->y, scale->z);
 }
 
-void OpenGLRenderer::bindFrameBufferTexture(Texture *texture) {
-	if(currentFrameBufferTexture) {
-		previousFrameBufferTexture = currentFrameBufferTexture;
-	}
+void OpenGLRenderer::bindFrameBufferTextureDepth(Texture *texture) {
+	if(!texture)
+		return;
 	OpenGLTexture *glTexture = (OpenGLTexture*)texture;
+	glBindFramebufferEXT(GL_RENDERBUFFER_EXT, glTexture->getFrameBufferID());
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
+}
 
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, glTexture->getFrameBufferID());
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-	currentFrameBufferTexture = texture;
+void OpenGLRenderer::bindFrameBufferTexture(Texture *texture) {
+	if(!texture)
+		return;
+	OpenGLTexture *glTexture = (OpenGLTexture*)texture;
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, glTexture->getFrameBufferID());
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
 }
 
 void OpenGLRenderer::unbindFramebuffers() {
-	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);	
-	currentFrameBufferTexture = NULL;
-	if(previousFrameBufferTexture) {
-		bindFrameBufferTexture(previousFrameBufferTexture);
-		previousFrameBufferTexture = NULL;
-	}
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+	glBindFramebufferEXT(GL_RENDERBUFFER_EXT, 0);
 }
 
-
 void OpenGLRenderer::createRenderTextures(Texture **colorBuffer, Texture **depthBuffer, int width, int height, bool floatingPointBuffer) {
 			
 	GLuint depthTexture,colorTexture;
@@ -627,7 +627,7 @@ void OpenGLRenderer::createRenderTextures(Texture **colorBuffer, Texture **depth
 
 	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 	if(status == GL_FRAMEBUFFER_COMPLETE_EXT) {
-		Logger::log("color fbo generation successful\n");
+//		Logger::log("color fbo generation successful\n");
 	} else {
 		Logger::log("color fbo generation failed\n");	
 	}
@@ -662,7 +662,7 @@ void OpenGLRenderer::createRenderTextures(Texture **colorBuffer, Texture **depth
 		status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
 
 		if(status == GL_FRAMEBUFFER_COMPLETE_EXT) {
-			Logger::log("depth fbo generation successful\n");
+//			Logger::log("depth fbo generation successful\n");
 		} else {
 			Logger::log("depth fbo generation failed\n");	
 		}

+ 1 - 1
Core/Contents/Source/PolyGLSLShader.cpp

@@ -198,7 +198,7 @@ void GLSLShader::linkProgram() {
 		name[name_len] = 0;
 		GLuint location = glGetUniformLocation( shader_id, name );
 		
-		if(String(name).find("gl_") == -1) {
+		if(!(String(name).find("gl_") == 0)) {
 		switch(type) {
 			case GL_SAMPLER_2D:
 				expectedTextures.push_back(String(name));

+ 32 - 23
Core/Contents/Source/PolyGLSLShaderModule.cpp

@@ -428,40 +428,49 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
 	}
 		
 	for(int i=0; i < cgBinding->textures.size(); i++) {
-		int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->textures[i].name.c_str());
-		glUniform1i(texture_location, textureIndex);
-		glActiveTexture(GL_TEXTURE0 + textureIndex);		
-		glBindTexture(GL_TEXTURE_2D, ((OpenGLTexture*)cgBinding->textures[i].texture)->getTextureID());	
-		textureIndex++;
+		OpenGLTexture *glTexture = (OpenGLTexture*)cgBinding->textures[i].texture;	
+		if(glTexture) {		
+			int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->textures[i].name.c_str());
+			glUniform1i(texture_location, textureIndex);
+			glActiveTexture(GL_TEXTURE0 + textureIndex);		
+			glBindTexture(GL_TEXTURE_2D, glTexture->getTextureID());
+			textureIndex++;
+		}
 	}	
 	
 		
 	for(int i=0; i < cgBinding->cubemaps.size(); i++) {
-		int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->cubemaps[i].name.c_str());
-		glUniform1i(texture_location, textureIndex);
-		
-		glActiveTexture(GL_TEXTURE0 + textureIndex);				
-		glBindTexture(GL_TEXTURE_CUBE_MAP, ((OpenGLCubemap*)cgBinding->cubemaps[i].cubemap)->getTextureID());
-		printf("BINDING %d\n", ((OpenGLCubemap*)cgBinding->cubemaps[i].cubemap)->getTextureID());
-		textureIndex++;
+		OpenGLCubemap *glCubemap = (OpenGLCubemap*)cgBinding->cubemaps[i].cubemap;
+		if(glCubemap) {
+			int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->cubemaps[i].name.c_str());
+			glUniform1i(texture_location, textureIndex);		
+			glActiveTexture(GL_TEXTURE0 + textureIndex);				
+			glBindTexture(GL_TEXTURE_CUBE_MAP, glCubemap->getTextureID());
+			textureIndex++;
+		}
 	}	
 	
 	cgBinding = (GLSLShaderBinding*)localOptions;
 	for(int i=0; i < cgBinding->textures.size(); i++) {
-		int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->textures[i].name.c_str());
-		glUniform1i(texture_location, textureIndex);
-		glActiveTexture(GL_TEXTURE0 + textureIndex);		
-		glBindTexture(GL_TEXTURE_2D, ((OpenGLTexture*)cgBinding->textures[i].texture)->getTextureID());	
-		textureIndex++;
+		OpenGLTexture *glTexture = (OpenGLTexture*)cgBinding->textures[i].texture;
+		if(glTexture) {		
+			int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->textures[i].name.c_str());
+			glUniform1i(texture_location, textureIndex);
+			glActiveTexture(GL_TEXTURE0 + textureIndex);		
+			glBindTexture(GL_TEXTURE_2D, glTexture->getTextureID());	
+			textureIndex++;
+		}
 	}		
 
 	for(int i=0; i < cgBinding->cubemaps.size(); i++) {
-		int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->cubemaps[i].name.c_str());
-		glUniform1i(texture_location, textureIndex);
-		
-		glActiveTexture(GL_TEXTURE0 + textureIndex);				
-		glBindTexture(GL_TEXTURE_CUBE_MAP, ((OpenGLCubemap*)cgBinding->cubemaps[i].cubemap)->getTextureID());
-		textureIndex++;
+		OpenGLCubemap *glCubemap = (OpenGLCubemap*)cgBinding->cubemaps[i].cubemap;	
+		if(glCubemap) {
+			int texture_location = glGetUniformLocation(glslShader->shader_id, cgBinding->cubemaps[i].name.c_str());
+			glUniform1i(texture_location, textureIndex);		
+			glActiveTexture(GL_TEXTURE0 + textureIndex);				
+			glBindTexture(GL_TEXTURE_CUBE_MAP, glCubemap->getTextureID());
+			textureIndex++;
+		}
 	}	
 
 		 

+ 93 - 2
Core/Contents/Source/PolyMaterial.cpp

@@ -25,6 +25,8 @@
 #include "PolyShader.h"
 #include "PolyRenderer.h"
 #include "PolyCoreServices.h"
+#include "PolyCore.h"
+#include "PolyTexture.h"
 
 using namespace Polycode;
 
@@ -33,6 +35,7 @@ Material::Material(const String& name) : Resource(Resource::RESOURCE_MATERIAL) {
 	fp16RenderTargets = false;
 	shaderModule = NULL;
 	blendingMode = Renderer::BLEND_MODE_NORMAL;
+	screenMaterial = false;
 }
 
 Material::~Material() {
@@ -70,6 +73,66 @@ void Material::clearShaders() {
 	renderTargets.clear();		
 }
 
+void Material::recreateRenderTargets() {
+	for(int i=0; i < renderTargets.size(); i++) {
+		recreateRenderTarget(renderTargets[i]);
+	}
+}
+
+void Material::recreateRenderTarget(ShaderRenderTarget *renderTarget) {
+	int textureWidth;
+	int textureHeight;
+	Texture *newTexture;
+	
+	if(renderTarget->sizeMode == ShaderRenderTarget::SIZE_MODE_NORMALIZED) {
+		Number safeWidth = renderTarget->width;
+		Number safeHeight = renderTarget->height;		
+		if(safeWidth > 1.0)
+			safeWidth = 1.0;
+		if(safeHeight > 1.0)
+			safeHeight = 1.0;
+			
+		if(safeWidth < 0.0)
+			safeWidth = 0.0;
+		if(safeHeight < 0.0)
+			safeHeight = 0.0;
+		
+		if(renderTarget->normalizedWidth > 0 && renderTarget->normalizedHeight > 0) {
+			textureWidth = (int) (renderTarget->normalizedWidth * safeWidth);
+			textureHeight = (int) (renderTarget->normalizedHeight * safeHeight);		
+		} else {
+			textureWidth = (int) (CoreServices::getInstance()->getCore()->getXRes() * safeWidth);
+			textureHeight = (int) (CoreServices::getInstance()->getCore()->getYRes() * safeHeight);
+		}
+	} else {
+		textureWidth = (int)renderTarget->width;
+		textureHeight = (int)renderTarget->height;		
+	}
+	
+	CoreServices::getInstance()->getRenderer()->createRenderTextures(&newTexture, NULL, textureWidth, textureHeight, fp16RenderTargets);
+	newTexture->setResourceName(renderTarget->id);
+	
+	Texture *oldTexture = renderTarget->texture;
+	renderTarget->texture = newTexture;
+
+	if(oldTexture) {	
+		for(int i=0; i < shaderBindings.size(); i++) {
+				
+			for(int j=0; j < shaderBindings[i]->getNumRenderTargetBindings(); j++) {
+				if(shaderBindings[i]->getRenderTargetBinding(j)->texture == oldTexture) {
+					shaderBindings[i]->getRenderTargetBinding(j)->texture = newTexture;
+					shaderBindings[i]->getRenderTargetBinding(j)->width = newTexture->getWidth();
+					shaderBindings[i]->getRenderTargetBinding(j)->height = newTexture->getHeight();
+					shaderBindings[i]->clearTexture(shaderBindings[i]->getRenderTargetBinding(j)->name);
+					shaderBindings[i]->addTexture(shaderBindings[i]->getRenderTargetBinding(j)->name, newTexture);					
+				}
+			}			
+		}
+		
+		CoreServices::getInstance()->getRenderer()->destroyTexture(oldTexture);
+	}
+}
+
 void Material::handleEvent(Event *event) {
 	std::vector<Shader*> _materialShaders = materialShaders;
 	clearShaders();
@@ -79,13 +142,33 @@ void Material::handleEvent(Event *event) {
 	}	
 	dispatchEvent(new Event(), Event::RESOURCE_RELOAD_EVENT);	
 }
+
+void Material::removeShader(int shaderIndex) {
+	if(shaderIndex >= 0 && shaderIndex < materialShaders.size()) {
+		materialShaders.erase(materialShaders.begin() + shaderIndex);
+		shaderBindings.erase(shaderBindings.begin() + shaderIndex);		
+	}
+}
+
+void Material::addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex) {
+	materialShaders.insert(materialShaders.begin()+shaderIndex, shader);
+	shaderBindings.insert(shaderBindings.begin()+shaderIndex, shaderBinding);
+	
+	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);	
+	CoreServices::getInstance()->getRenderer()->setRendererShaderParams(shader, shaderBinding);	
+	
+	for(int i=0; i < shader->expectedParams.size(); i++) {
+		if(!shaderBinding->getLocalParamByName(shader->expectedParams[i].name)) {
+			shaderBinding->addParam(shader->expectedParams[i].type, shader->expectedParams[i].name);
+		}
+	}
+}
 			
 void Material::addShader(Shader *shader,ShaderBinding *shaderBinding) {
 	materialShaders.push_back(shader);
 	shaderBindings.push_back(shaderBinding);
 	
-	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
-	
+	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);	
 	CoreServices::getInstance()->getRenderer()->setRendererShaderParams(shader, shaderBinding);	
 	
 	for(int i=0; i < shader->expectedParams.size(); i++) {
@@ -135,3 +218,11 @@ int Material::getNumShaderRenderTargets() {
 ShaderRenderTarget *Material::getShaderRenderTarget(unsigned int index) {
 	return renderTargets[index];
 }
+
+void Material::removeShaderRenderTarget(int index) {
+	if(index >= 0 && index < renderTargets.size()) {
+		ShaderRenderTarget *renderTarget = renderTargets[index];
+		renderTargets.erase(renderTargets.begin() + index);
+		delete renderTarget;
+	}
+}

+ 17 - 15
Core/Contents/Source/PolyMaterialManager.cpp

@@ -398,10 +398,15 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 	
 	vector<Shader*> materialShaders;
 	vector<ShaderBinding*> newShaderBindings;
-	vector<ShaderRenderTarget*> renderTargets;	
+	vector<ShaderRenderTarget*> renderTargets;
 
 	Material *newMaterial = new Material(mname);
 	
+	if(nodeElement->Attribute("screen")) {
+		if(String(nodeElement->Attribute("screen")) == "true") {
+			newMaterial->screenMaterial = true;
+		}
+	}	
 	
 	if(nodeElement->Attribute("blendingMode")) {
 		newMaterial->blendingMode = atoi(nodeElement->Attribute("blendingMode"));
@@ -434,24 +439,19 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 						newTarget->height = atof(pChildElement->Attribute("height"));	
 						if(pChildElement->Attribute("sizeMode")) {
 							if(strcmp(pChildElement->Attribute("sizeMode"), "normalized") == 0) {
+								newTarget->sizeMode = ShaderRenderTarget::SIZE_MODE_NORMALIZED;	
 								if(newTarget->width > 1.0f)
 									newTarget->width = 1.0f;
 								if(newTarget->height > 1.0f)
 									newTarget->height = 1.0f;
-									
-								newTarget->width = ((Number)CoreServices::getInstance()->getRenderer()->getXRes()) * newTarget->width;
-								newTarget->height = ((Number)CoreServices::getInstance()->getRenderer()->getYRes()) * newTarget->height;
 							}						
 						}
-					}						
-//					Texture *newTexture = CoreServices::getInstance()->getMaterialManager()->createNewTexture(newTarget->width, newTarget->height, true);
-					Texture *newTexture, *temp;
-					CoreServices::getInstance()->getRenderer()->createRenderTextures(&newTexture, &temp, (int)newTarget->width, (int)newTarget->height, newMaterial->fp16RenderTargets);
-					newTexture->setResourceName(newTarget->id);
-					//CoreServices::getInstance()->getResourceManager()->addResource(newTexture);
-					newTarget->texture = newTexture;
+					}
+					
+					newTarget->normalizedWidth = -1;
+					newTarget->normalizedHeight = -1;					
+					newMaterial->recreateRenderTarget(newTarget);					
 					renderTargets.push_back(newTarget);
-
 				}
 			}
 		}	
@@ -544,14 +544,16 @@ Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
 								}
 								String mode = pChild2Element->Attribute("mode");
 								if(strcmp(mode.c_str(), "in") == 0) {
-									newBinding->mode = RenderTargetBinding::MODE_IN;
+									newBinding->mode = RenderTargetBinding::MODE_IN;			
+								} else if(strcmp(mode.c_str(), "color") == 0) {
+									newBinding->mode = RenderTargetBinding::MODE_COLOR;
+								} else if(strcmp(mode.c_str(), "depth") == 0) {
+									newBinding->mode = RenderTargetBinding::MODE_DEPTH;
 								} else {
 									newBinding->mode = RenderTargetBinding::MODE_OUT;								
 								}
 																
 								newShaderBinding->addRenderTargetBinding(newBinding);
-								//Texture *texture =  (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, newBinding->id);
-//								newBinding->texture = texture;
 								
 								for(int l=0; l < renderTargets.size(); l++) {
 									if(renderTargets[l]->id == newBinding->id) {

+ 0 - 4
Core/Contents/Source/PolyRenderer.cpp

@@ -32,8 +32,6 @@ Renderer::Renderer() : clearColor(0.2f, 0.2f, 0.2f, 0.0), currentTexture(NULL),
 	numLights = 0;
 	exposureLevel = 1;
 	shadersEnabled = true;
-	currentFrameBufferTexture = NULL;
-	previousFrameBufferTexture = NULL;
 	currentMaterial = NULL;
 	numLights = 0;
 	numAreaLights = 0;
@@ -41,8 +39,6 @@ Renderer::Renderer() : clearColor(0.2f, 0.2f, 0.2f, 0.0), currentTexture(NULL),
 	exposureLevel = 1;
 	shadersEnabled = true;
 	currentShaderModule = NULL;
-	currentFrameBufferTexture = NULL;
-	previousFrameBufferTexture = NULL;
 	fov = 45.0;
 	setAmbientColor(0.0,0.0,0.0);
 	cullingFrontFaces = false;

+ 0 - 420
Core/Contents/Source/PolyScene.cpp

@@ -314,405 +314,6 @@ SceneLight *Scene::getNearestLight(Vector3 pos) {
 		return NULL;
 }
 
-
-String Scene::readString(OSFILE *inFile) {
-	char buffer[1024];
-	unsigned int namelen;
-	OSBasics::read(&namelen, sizeof(unsigned int), 1, inFile);
-	memset(buffer, 0, 1024);
-	OSBasics::read(buffer, 1, namelen, inFile);
-	return String(buffer);
-}
-
-void Scene::loadScene(const String& fileName) {
-	OSFILE *inFile = OSBasics::open(fileName.c_str(), "rb");
-	if(!inFile) {
-		Logger::log("Error opening scene file\n");
-		return;
-	}
-	
-	Number r,g,b,a;
-	
-	OSBasics::read(&r, sizeof(Number), 1, inFile);
-	OSBasics::read(&g, sizeof(Number), 1, inFile);
-	OSBasics::read(&b, sizeof(Number), 1, inFile);
-	clearColor.setColor(r,g,b,1.0f);
-	
-	OSBasics::read(&r, sizeof(Number), 1, inFile);
-	OSBasics::read(&g, sizeof(Number), 1, inFile);
-	OSBasics::read(&b, sizeof(Number), 1, inFile);
-	ambientColor.setColor(r,g,b,1.0f);
-	
-	
-	unsigned int numObjects, objectType,namelen;
-	char buffer[1024];
-	char flag;
-	Number t[3],rq[4];
-	SceneEntity *newEntity;
-	
-	unsigned int lightmapIndex = 0;
-	
-	OSBasics::read(&flag, 1, 1, inFile);
-	hasLightmaps = false;
-	if(flag == 1)
-		hasLightmaps = true;
-	
-	OSBasics::read(&numObjects, sizeof(unsigned int), 1, inFile);
-	Logger::log("Loading scene (%d objects)\n", numObjects);
-	for(int i=0; i < numObjects; i++) {
-		
-		OSBasics::read(t, sizeof(Number), 3, inFile);
-		OSBasics::read(rq, sizeof(Number), 4, inFile);
-		newEntity = NULL;
-		
-		OSBasics::read(&objectType, sizeof(unsigned int), 1, inFile);
-		
-		SceneMesh *newSceneMesh;
-		Mesh *newMesh;
-		Material *newMaterial;
-		
-		switch(objectType) {
-			case ENTITY_MESH:			
-				
-				if(hasLightmaps) {
-					OSBasics::read(&lightmapIndex, sizeof(unsigned int), 1, inFile);			
-				} else {
-					lightmapIndex = 0;
-				}
-				
-				
-				OSBasics::read(&namelen, sizeof(unsigned int), 1, inFile);
-				memset(buffer, 0, 1024);
-				OSBasics::read(buffer, 1, namelen, inFile);
-				
-				Logger::log("adding mesh (texture: %s)\n", buffer);
-				
-				OSBasics::read(&r, sizeof(Number), 1, inFile);
-				OSBasics::read(&g, sizeof(Number), 1, inFile);
-				OSBasics::read(&b, sizeof(Number), 1, inFile);
-				OSBasics::read(&a, sizeof(Number), 1, inFile);
-				
-				newMaterial = (Material*) CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, buffer);
-				newMesh = new Mesh(Mesh::TRI_MESH);
-				newMesh->loadFromFile(inFile);
-				newSceneMesh = new SceneMesh(newMesh);
-				
-				newSceneMesh->setColor(r,g,b,a);
-				newSceneMesh->lightmapIndex = lightmapIndex;
-				addEntity(newSceneMesh);
-				newEntity = (SceneEntity*)newSceneMesh;
-				staticGeometry.push_back(newSceneMesh);
-				if(newMaterial != NULL)
-					newSceneMesh->setMaterial(newMaterial);
-				
-				break;
-			case ENTITY_ENTITY: {
-				Logger::log("loading entity\n");
-				String entityType = readString(inFile);					
-				SceneEntity *newCustomEntity = new SceneEntity();
-				newCustomEntity->custEntityType = entityType;					
-				newEntity = newCustomEntity;
-				customEntities.push_back(newCustomEntity);					
-			} break;
-			case ENTITY_COLLMESH: {
-			/*
-				unsigned int collType,numVertices,numFaces;
-				Number co[3];
-				OSBasics::read(&collType, sizeof(unsigned int), 1, inFile);
-				OSBasics::read(&numVertices, sizeof(unsigned int), 1, inFile);
-				
-				Mesh *mesh = new Mesh(Mesh::TRI_MESH);
-				
-				for(int i=0; i < numVertices; i++) {
-					OSBasics::read(co, sizeof(Number), 3, inFile);
-					Vertex *newVert = new Vertex(co[0], co[1], co[2]);
-					mesh->addVertex(newVert);
-				}
-				
-				OSBasics::read(&numFaces, sizeof(unsigned int), 1, inFile);
-				
-				unsigned int fo[3];
-				for(int i=0; i < numFaces; i++) {
-					OSBasics::read(fo, sizeof(unsigned int), 3, inFile);						
-					Polygon *newPoly = new Polygon();
-					newPoly->addVertex(mesh->getVertex(fo[0]));
-					newPoly->addVertex(mesh->getVertex(fo[1]));
-					newPoly->addVertex(mesh->getVertex(fo[2]));
-					mesh->addPolygon(newPoly);
-				}
-				
-				SceneMesh *newMesh = new SceneMesh(mesh);
-				newEntity = newMesh;
-				loadCollisionChild(newEntity);
-				collisionGeometry.push_back(newMesh);
-				newMesh->visible = false;
-				
-				//					ScenePrimitive *test = new ScenePrimitive(ScenePrimitive::TYPE_BOX, newMesh->bBox.x,newMesh->bBox.y,newMesh->bBox.z);				
-				//					newMesh->addEntity(test);
-				*/
-			}
-			
-				break;
-			case ENTITY_CAMERA:
-				newEntity = (SceneEntity*)this->getDefaultCamera();
-				break;
-			case ENTITY_LIGHT:
-				/*
-				Number col[3],e,d;
-				unsigned int lType;
-				OSBasics::read(&lType, sizeof(unsigned int), 1, inFile);				
-				OSBasics::read(&e, sizeof(Number), 1, inFile);
-				OSBasics::read(&d, sizeof(Number), 1, inFile);
-				OSBasics::read(col, sizeof(Number), 3, inFile);
-				
-				SceneLight *newLight = new SceneLight(lType, e, d, this);
-				newLight->lightColor.setColor(col[0],col[1],col[2],1.0f);
-				addLight(newLight);
-				newEntity = (SceneEntity*)newLight;
-				*/
-				break;
-		}
-		
-		
-		if(newEntity != NULL) {		
-			unsigned int numProps;
-			OSBasics::read(&numProps, sizeof(unsigned int), 1, inFile);
-			for(int i=0; i < numProps; i++) {
-				String propName,propValue;
-				propName = readString(inFile);
-				propValue = readString(inFile);
-				EntityProp prop;
-				prop.propName = propName;
-				prop.propValue = propValue;
-				newEntity->entityProps.push_back(prop);
-			}						
-			
-			if(objectType == ENTITY_MESH) {
-				if(newEntity->getEntityProp("vertexnormals") == "false")
-					((SceneMesh*)newEntity)->getMesh()->useVertexNormals(false);
-				
-				if(newEntity->getEntityProp("collision") != "") {
-					if(newEntity->getEntityProp("collision")  == "mesh") {
-						loadCollisionChild(newEntity, false, 3);
-					}
-				}
-			}
-			
-			newEntity->setPosition(t[0], t[1], t[2]);
-			newEntity->setRotationQuat(rq[0], rq[1], rq[2], rq[3]);
-			newEntity->rebuildTransformMatrix();						
-		}		
-	}
-	
-	if(!hasLightmaps) {
-		OSBasics::close(inFile);
-		return;
-	}
-	/*
-	 unsigned int lmsize,numLightmaps,imageWidth, imageHeight;
-	 OSBasics::read(&numLightmaps, sizeof(unsigned int), 1, inFile);
-	 
-	 packer = new LightmapPacker(this);
-	 char *imageData;
-	 
-	 for(int i=0 ; i < numLightmaps; i++) {
-	 OSBasics::read(&imageWidth, sizeof(unsigned int), 1, inFile);
-	 OSBasics::read(&imageHeight, sizeof(unsigned int), 1, inFile);
-	 OSBasics::read(&lmsize, sizeof(unsigned int), 1, inFile);
-	 imageData = (char*)malloc(lmsize);
-	 OSBasics::read(imageData, 1, lmsize, inFile);
-	 Image *newImage = new Image(imageData, imageWidth, imageHeight);
-	 packer->images.push_back(newImage);	
-	 free(imageData);
-	 }
-	 
-	 packer->bindTextures();
-	 */
-	OSBasics::close(inFile);
-}
-
-vector<SceneEntity*> Scene::getCustomEntitiesByType(const String& type) const {
-	vector<SceneEntity*> retVector;
-	for(int i=0; i < customEntities.size(); i++) {
-		if(customEntities[i]->custEntityType == type) {
-			retVector.push_back(customEntities[i]);
-		}
-	}
-	return retVector;	
-}
-
-SceneEntity *Scene::getCustomEntityByType(const String& type) const {
-	for(int i=0; i < customEntities.size(); i++) {
-		if(customEntities[i]->custEntityType == type) {
-			return customEntities[i];
-		}
-	}
-	return NULL;
-}
-
-void Scene::writeEntityMatrix(SceneEntity *entity, OSFILE *outFile) {
-	Number t[3],rq[4];
-	Vector3 pos = entity->getPosition();
-	t[0] = pos.x;
-	t[1] = pos.y;
-	t[2] = pos.z;
-	
-	rq[0] = entity->getRotationQuat().w;
-	rq[1] = entity->getRotationQuat().x;
-	rq[2] = entity->getRotationQuat().y;
-	rq[3] = entity->getRotationQuat().z;						
-	
-	OSBasics::write(t, sizeof(Number), 3, outFile);
-	OSBasics::write(rq, sizeof(Number), 4, outFile);
-	
-}
-
-void Scene::saveScene(const String& fileName) {
-	OSFILE *outFile = OSBasics::open(fileName.c_str(), "wb");
-	if(!outFile) {
-		Logger::log("Error opening scene file for writing\n");
-		return;
-	}
-	
-	// geometry
-	unsigned int totalObjects = staticGeometry.size() + lights.size() + collisionGeometry.size() + customEntities.size();
-	unsigned int objType;
-	char flag = 0;
-	if(hasLightmaps)
-		flag = 1;
-	OSBasics::write(&flag, 1, 1, outFile);
-	OSBasics::write(&totalObjects, sizeof(unsigned int), 1, outFile);
-	
-	unsigned int stLen;
-	
-	for(int i=0; i <staticGeometry.size(); i++) {
-		SceneMesh *mesh = staticGeometry[i];
-		
-		writeEntityMatrix(mesh, outFile);
-		
-		objType = Scene::ENTITY_MESH;		
-		OSBasics::write(&objType, sizeof(unsigned int), 1, outFile);
-		
-		if(hasLightmaps) {
-			unsigned int lightmapIndex = mesh->lightmapIndex;
-			OSBasics::write(&lightmapIndex, sizeof(unsigned int), 1, outFile);			
-		}
-		
-		stLen = mesh->getMaterial()->getName().length();
-		OSBasics::write(&stLen, sizeof(unsigned int), 1, outFile);
-		OSBasics::write(mesh->getMaterial()->getName().c_str(), 1, stLen, outFile);
-		
-		mesh->getMesh()->saveToFile(outFile);		
-	}
-	
-	/*
-	for(int i=0; i < collisionGeometry.size(); i++) {
-		SceneMesh *mesh = collisionGeometry[i];
-		writeEntityMatrix(mesh, outFile);
-		objType = Scene::ENTITY_COLLMESH;
-		OSBasics::write(&objType, sizeof(unsigned int), 1, outFile);
-		
-		unsigned int collType = 1;
-		OSBasics::write(&collType, sizeof(unsigned int), 1, outFile);
-		
-		unsigned int numVertices = mesh->getMesh()->getNumVertices();
-		OSBasics::write(&numVertices, sizeof(unsigned int), 1, outFile);
-		Number pos[3];
-		for(int j=0; j < numVertices; j++) {
-			Vertex *vert = mesh->getMesh()->getVertex(j);
-			pos[0] = vert->x;
-			pos[1] = vert->y;
-			pos[2] = vert->z;			
-			OSBasics::write(pos, sizeof(Number),3, outFile);
-		}
-		
-		unsigned int numFaces = mesh->getMesh()->getPolygonCount();
-		OSBasics::write(&numFaces, sizeof(unsigned int), 1, outFile);
-		unsigned int ind[3];
-		for(int j=0; j < numFaces; j++) {
-			Polygon *poly = mesh->getMesh()->getPolygon(j);
-			ind[0] = mesh->getMesh()->getVertexIndex(poly->getVertex(0));
-			ind[1] = mesh->getMesh()->getVertexIndex(poly->getVertex(1));
-			ind[2] = mesh->getMesh()->getVertexIndex(poly->getVertex(2));			
-			OSBasics::write(ind, sizeof(unsigned int),3, outFile);
-		}
-	}
-	*/
-	/*
-	Number col[3],e,d;
-	for(int i=0; i < lights.size(); i++) {
-		
-		writeEntityMatrix(lights[i], outFile);
-		objType = Scene::ENTITY_LIGHT;		
-		OSBasics::write(&objType, sizeof(unsigned int), 1, outFile);
-		
-		col[0] = lights[i]->lightColor.r;
-		col[1] = lights[i]->lightColor.g;
-		col[2] = lights[i]->lightColor.b;
-		e = lights[i]->getIntensity();
-		d = lights[i]->getDistance();
-		
-		OSBasics::write(&e, sizeof(Number), 1, outFile);
-		OSBasics::write(&d, sizeof(Number), 1, outFile);
-		OSBasics::write(col, sizeof(Number), 3, outFile);
-	}
-	*/
-	for(int i=0; i < customEntities.size(); i++) {
-		SceneEntity *custEnt = customEntities[i];
-		
-		writeEntityMatrix(custEnt, outFile);	
-		objType = Scene::ENTITY_ENTITY;
-		OSBasics::write(&objType, sizeof(unsigned int), 1, outFile);
-		
-		
-		writeString(custEnt->custEntityType, outFile);
-		unsigned int numProps = custEnt->entityProps.size();
-		OSBasics::write(&numProps, sizeof(unsigned int), 1, outFile);		
-		for(int j=0; j < numProps; j++) {
-			writeString(custEnt->entityProps[j].propName, outFile);
-			writeString(custEnt->entityProps[j].propValue, outFile);
-		}
-	}
-	
-	if(!hasLightmaps) {
-		OSBasics::close(outFile);
-		return;
-	}
-	
-	/*
-	 unsigned int lmsize;
-	 lmsize = packer->images.size();
-	 OSBasics::write(&lmsize, sizeof(unsigned int), 1, outFile);
-	 for(int i=0; i < packer->images.size(); i++) {
-	 lmsize = packer->images[i]->getWidth();
-	 OSBasics::write(&lmsize, sizeof(unsigned int), 1, outFile);
-	 lmsize = packer->images[i]->getHeight();
-	 OSBasics::write(&lmsize, sizeof(unsigned int), 1, outFile);
-	 
-	 lmsize = packer->images[i]->getWidth() * packer->images[i]->getHeight() * 4;
-	 OSBasics::write(&lmsize, sizeof(unsigned int), 1, outFile);
-	 OSBasics::write(packer->images[i]->getPixels(), 1, lmsize, outFile);
-	 }
-	 */
-	
-	OSBasics::close(outFile);
-}
-
-void Scene::writeString(const String& str, OSFILE *outFile) {
-	unsigned int stLen = str.length();
-	OSBasics::write(&stLen, sizeof(unsigned int), 1, outFile);
-	OSBasics::write(str.c_str(), 1, stLen, outFile);
-	
-}
-
-int Scene::getNumStaticGeometry() {
-	return staticGeometry.size();
-}
-
-SceneMesh *Scene::getStaticGeometry(int index) {
-	return staticGeometry[index];
-}
-
 int Scene::getNumLights() {
 	return lights.size();
 }
@@ -721,24 +322,3 @@ SceneLight *Scene::getLight(int index) {
 	return lights[index];
 }
 
-void Scene::generateLightmaps(Number lightMapRes, Number lightMapQuality, int numRadPasses) {
-	/*	
-	 packer = new LightmapPacker(this);
-	 packer->generateTextures(lightMapRes, lightMapQuality);
-	 
-	 RadTool *radTool = new RadTool(this, packer);
-	 radTool->fiatLux(numRadPasses);
-	 
-	 packer->bindTextures();
-	 packer->saveLightmaps("/Users/ivansafrin/Desktop/lightmaps");
-	 hasLightmaps = true;
-	 */
-}
-/*
-void Scene::addGrid(String gridTexture) {
-	ScenePrimitive *gridMesh = new ScenePrimitive(ScenePrimitive::TYPE_PLANE, 20,20,0);
-	gridMesh->loadTexture(gridTexture);
-	gridMesh->setPitch(-90.0f);
-	addEntity(gridMesh);
-}
-*/

+ 13 - 7
Core/Contents/Source/PolySceneRenderTexture.cpp

@@ -29,20 +29,26 @@
 using namespace Polycode;
 
 SceneRenderTexture::SceneRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight, bool floatingPoint) {
-//	targetTexture = CoreServices::getInstance()->getMaterialManager()->createTexture(renderWidth, renderHeight, NULL,true);
+	this->floatingPoint = floatingPoint;
 	CoreServices::getInstance()->getRenderer()->createRenderTextures(&targetTexture, &depthTexture, renderWidth, renderHeight, floatingPoint);
 	this->targetScene = targetScene;
 	this->targetCamera = targetCamera;
-	
-	
+
 	CoreServices::getInstance()->getRenderer()->createRenderTextures(&filterColorBufferTexture, &filterZBufferTexture, renderWidth, renderHeight, floatingPoint);
-	
-	
 	CoreServices::getInstance()->getSceneManager()->registerRenderTexture(this);
 }
 
-void SceneRenderTexture::drawScreen() {
-	//CoreServices::getInstance()->getRenderer()->renderToTexture(targetTexture);
+void SceneRenderTexture::resizeRenderTexture(int newWidth, int newHeight) {
+
+	if(newWidth > 0 && newHeight > 0) {
+		CoreServices::getInstance()->getRenderer()->destroyTexture(targetTexture);
+		CoreServices::getInstance()->getRenderer()->destroyTexture(depthTexture);	
+		CoreServices::getInstance()->getRenderer()->destroyTexture(filterColorBufferTexture);
+		CoreServices::getInstance()->getRenderer()->destroyTexture(filterZBufferTexture);	
+
+		CoreServices::getInstance()->getRenderer()->createRenderTextures(&targetTexture, &depthTexture, newWidth, newHeight, floatingPoint);
+		CoreServices::getInstance()->getRenderer()->createRenderTextures(&filterColorBufferTexture, &filterZBufferTexture, newWidth, newHeight, floatingPoint);
+	}
 }
 	
 Scene *SceneRenderTexture::getTargetScene() {

+ 9 - 6
Core/Contents/Source/PolyScreen.cpp

@@ -118,13 +118,9 @@ void Screen::setScreenShader(const String& shaderName) {
 	}
 	
 	for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
-		ShaderBinding* binding = filterShaderMaterial->getShader(i)->createBinding();		
-		if( i == 0) 
-			binding->addTexture("screenColorBuffer", originalSceneTexture);
-			
+		ShaderBinding* binding = filterShaderMaterial->getShader(i)->createBinding();	
 		localShaderOptions.push_back(binding);
-	}
-		
+	}	
 	_hasFilterShader = true;
 	
 }
@@ -152,6 +148,13 @@ void Screen::drawFilter() {
 	ShaderBinding* materialBinding;		
 	for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
 		materialBinding = filterShaderMaterial->getShaderBinding(i);
+		
+		for(int j=0; j < materialBinding->getNumColorTargetBindings(); j++) {
+			RenderTargetBinding *colorBinding = materialBinding->getColorTargetBinding(j);
+			materialBinding->clearTexture(colorBinding->name);
+			materialBinding->addTexture(colorBinding->name, originalSceneTexture);
+		}
+		
 		renderer->applyMaterial(filterShaderMaterial, localShaderOptions[i], i);	
 			
 		if(i==filterShaderMaterial->getNumShaders()-1) {

+ 69 - 6
Core/Contents/Source/PolyShader.cpp

@@ -25,6 +25,10 @@
 
 using namespace Polycode;
 
+ShaderRenderTarget::ShaderRenderTarget() : PolyBase() {
+	texture = NULL;
+}
+
 void *ProgramParam::createParamData(int type) {
 	switch (type) {
 		case PARAM_NUMBER:
@@ -132,15 +136,58 @@ LocalShaderParam * ShaderBinding::addParam(int type, const String& name) {
 
 void ShaderBinding::addRenderTargetBinding(RenderTargetBinding *binding) {
 	renderTargetBindings.push_back(binding);
-	if(binding->mode == RenderTargetBinding::MODE_IN) {
-		inTargetBindings.push_back(binding);
-		printf("Adding in target binding [%s] [%s]\n", binding->id.c_str(), binding->name.c_str());
-	} else {
-		outTargetBindings.push_back(binding);	
-		printf("Adding out target binding [%s]\n", binding->id.c_str());		
+	switch (binding->mode) {
+		case RenderTargetBinding::MODE_IN:
+			inTargetBindings.push_back(binding);		
+		break;
+		case RenderTargetBinding::MODE_OUT:
+			outTargetBindings.push_back(binding);		
+		break;
+		case RenderTargetBinding::MODE_COLOR:
+			colorTargetBindings.push_back(binding);		
+		break;
+		case RenderTargetBinding::MODE_DEPTH:
+			depthTargetBindings.push_back(binding);		
+		break;				
 	}
 }
 
+void ShaderBinding::removeRenderTargetBinding(RenderTargetBinding *binding) {
+	for(int i=0; i < renderTargetBindings.size(); i++) {
+		if(renderTargetBindings[i] == binding) {
+			renderTargetBindings.erase(renderTargetBindings.begin() + i);
+		}
+	}
+	
+	for(int i=0; i < inTargetBindings.size(); i++) {
+		if(inTargetBindings[i] == binding) {
+			inTargetBindings.erase(inTargetBindings.begin() + i);
+			return;
+		}
+	}
+	for(int i=0; i < outTargetBindings.size(); i++) {
+		if(outTargetBindings[i] == binding) {
+			outTargetBindings.erase(outTargetBindings.begin() + i);
+			return;
+		}
+	}
+	
+	for(int i=0; i < colorTargetBindings.size(); i++) {
+		if(colorTargetBindings[i] == binding) {
+			colorTargetBindings.erase(colorTargetBindings.begin() + i);
+			return;
+		}
+	}
+
+	for(int i=0; i < depthTargetBindings.size(); i++) {
+		if(depthTargetBindings[i] == binding) {
+			depthTargetBindings.erase(depthTargetBindings.begin() + i);
+			return;
+		}
+	}
+	
+}
+
 unsigned int ShaderBinding::getNumRenderTargetBindings() {
 	return renderTargetBindings.size();
 }
@@ -165,6 +212,22 @@ RenderTargetBinding *ShaderBinding::getOutTargetBinding(unsigned int index) {
 	return outTargetBindings[index];
 }
 
+unsigned int ShaderBinding::getNumColorTargetBindings() {
+	return colorTargetBindings.size();
+}
+
+RenderTargetBinding *ShaderBinding::getColorTargetBinding(unsigned int index) {
+	return colorTargetBindings[index];
+}
+
+unsigned int ShaderBinding::getNumDepthTargetBindings() {
+	return depthTargetBindings.size();
+}
+
+RenderTargetBinding *ShaderBinding::getDepthTargetBinding(unsigned int index) {
+	return depthTargetBindings[index];
+}
+
 
 Shader::Shader(int type) : Resource(Resource::RESOURCE_SHADER) {
 	numSpotLights = 0;

+ 3 - 2
Core/Contents/Source/PolyString.cpp

@@ -180,9 +180,10 @@ String String::toUpperCase() const {
 }
 
 
-String String::NumberToString(Number value) {
+String String::NumberToString(Number value, int precision) {
 	char temp[128];
-	sprintf(temp, "%.2f", value);
+	String precisionStr = String("%.")+IntToString(precision)+String("f");
+	sprintf(temp, precisionStr.c_str(), value);
 	return String(temp);
 }
 

+ 86 - 5
IDE/Contents/Include/PolycodeMaterialEditor.h

@@ -35,8 +35,11 @@ public:
 	MaterialBrowserData() {
 		material = NULL;
 		shader = NULL;
+		cubemap = NULL;
+		postMaterial = NULL;
 	}
 	Material *material;
+	Material *postMaterial;
 	Shader *shader;
 	Cubemap *cubemap;
 	String name;
@@ -65,8 +68,37 @@ class MaterialPreviewBox : public UIElement {
 		
 		ScreenEntity *previewBase;		
 		ScenePrimitive *previewPrimitive;	
-		Material *currentMaterial;			
+		Material *currentMaterial;					
+};
+
+class PostPreviewBox : public UIElement {
+	public:
+		PostPreviewBox();
+		~PostPreviewBox();
+		void setMaterial(Material *material);
+		void clearMaterial();		
+		void handleEvent(Event *event);
+		void Resize(Number width, Number height);
+		void Update();	
+			
+		Scene *previewScene;
+		SceneRenderTexture *renderTexture;
+		ScreenShape *previewShape;				
+		ScreenEntity *previewBase;		
+		ScenePrimitive *previewPrimitive;	
+		Material *currentMaterial;	
+		ScreenShape *headerBg;
+				
+		Number spinValue;
 		
+		UICheckBox *rotateCheckBox;
+		UICheckBox *hdrCheckBox;		
+		UITextInput *cameraExposureInput;
+		UITextInput *lightStrength;
+				
+		SceneLight	*mainLight;
+		SceneLight	*secondLight;
+
 };
 
 
@@ -80,7 +112,10 @@ class MaterialBrowser : public UIElement {
 		UITree *addMaterial(Material *material);
 		UITree *addShader(Shader *shader);
 		UITree *addCubemap(Cubemap *cubemap);
-						
+		UITree *addPostMaterial(Material *material);
+		
+		void removeSelected();
+		
 		void handleEvent(Event *event);
 		
 		MaterialBrowserData *selectedData;
@@ -88,7 +123,10 @@ class MaterialBrowser : public UIElement {
 		UIImageButton *newShaderButton;	
 		UIImageButton *newMaterialButton;
 		UIImageButton *newCubemapButton;
-				
+		UIImageButton *newPostButton;
+		
+		UIImageButton *removeButton;
+								
 		UITree *selectedNode;
 														
 	protected:
@@ -128,6 +166,46 @@ class CubemapEditorPane : public UIElement {
 		MaterialPreviewBox *cubemapPreview;
 };
 
+class PostEditorPane : public UIElement {
+	public:
+		PostEditorPane();
+		~PostEditorPane();
+		void Resize(Number width, Number height);
+		void setMaterial(Material *material);
+		void handleEvent(Event *event);
+		Material *currentMaterial;	
+		
+		void adjustPreview();
+		
+		protected:
+		
+		ScreenShape *headerBgBottom;
+
+		PropList *propList;				
+		PropSheet *baseProps;
+		ShaderPassesSheet *passProps;
+		RenderTargetsSheet *targetsProps;
+	
+		PropList *optionsPropList;
+		
+		TargetBindingsSheet *targetBindingProps;
+		ShaderTexturesSheet *shaderTextureSheet;
+		ShaderOptionsSheet *shaderOptionsSheet;			
+			
+		UIVSizer *mainSizer;
+		UIElement *topElement;
+		UIElement *bottomElement;
+						
+		StringProp *nameProp;
+		BoolProp *fp16Prop;
+		
+		PostPreviewBox *postPreview;
+		
+		Screen *previewScreen;
+		
+					
+};
+
 class ShaderEditorPane : public UIElement {
 	public:
 		ShaderEditorPane();
@@ -157,7 +235,7 @@ class ShaderEditorPane : public UIElement {
 		
 		StringProp *nameProp;
 		BoolProp *screenShaderProp;
-		
+	
 		
 		NumberProp *areaLightsProp;
 		NumberProp *spotLightsProp;		
@@ -202,6 +280,7 @@ class MaterialMainWindow : public UIElement {
 	MaterialEditorPane *materialPane;
 	ShaderEditorPane *shaderPane;	
 	CubemapEditorPane *cubemapPane;	
+	PostEditorPane *postPane;	
 		
 	UIColorPicker *colorPicker;
 };
@@ -217,6 +296,7 @@ class PolycodeMaterialEditor : public PolycodeEditor {
 	
 	void handleEvent(Event *event);	
 	void saveFile();
+	void saveMaterials(ObjectEntry *materialsEntry, std::vector<Material*> materials);
 	
 	String createStringValue(unsigned int type, void *value);
 	
@@ -230,7 +310,8 @@ class PolycodeMaterialEditor : public PolycodeEditor {
 		std::vector<Material*> materials;
 		std::vector<Shader*> shaders;
 		std::vector<Cubemap*> cubemaps;
-						
+		std::vector<Material*> postMaterials;
+								
 		UITree *selectedMaterialNode;
 };
 

+ 124 - 4
IDE/Contents/Include/PolycodeProps.h

@@ -110,6 +110,64 @@ class NumberProp : public PropProp {
 		Number currentValue;
 };
 
+class TargetBindingProp : public PropProp {
+	public:
+
+		TargetBindingProp(Shader *shader, Material *material, ShaderBinding *binding, RenderTargetBinding *targetBinding);
+		~TargetBindingProp();
+
+		void handleEvent(Event *event);	
+		void setPropWidth(Number width);
+						
+		RenderTargetBinding *targetBinding;
+		Material *material;
+		Shader *shader;
+		ShaderBinding *binding;
+		
+		UIComboBox *typeComboBox;
+		UIComboBox *targetComboBox;
+		UIComboBox *textureComboBox;		
+		UIImageButton *removeButton;					
+	
+};
+
+class RenderTargetProp : public PropProp {
+	public:
+		RenderTargetProp(ShaderRenderTarget *renderTarget, Material *material);
+		~RenderTargetProp();
+
+		void handleEvent(Event *event);	
+		void setPropWidth(Number width);
+		
+		void recreateRenderTarget();
+		
+		Material *material;
+		ShaderRenderTarget *renderTarget;
+		
+		UITextInput *nameInput;		
+		UIComboBox *typeComboBox;		
+		UITextInput *widthInput;
+		UITextInput *heightInput;		
+		UIImageButton *removeButton;					
+};
+
+class ShaderPassProp : public PropProp {
+	public:
+		ShaderPassProp(Material *material, int shaderIndex);
+		~ShaderPassProp();
+		
+		void handleEvent(Event *event);	
+		void setPropWidth(Number width);
+		
+		Material *material;
+		Shader *shader;		
+		int shaderIndex;
+		UIComboBox *shaderComboBox;		
+		UIImageButton *removeButton;
+		
+		UIButton *editButton;
+		
+};
 
 class CustomProp : public PropProp {
 	public:
@@ -247,7 +305,8 @@ class TextureProp : public PropProp {
 		TextureProp(String caption);
 		~TextureProp();
 		void handleEvent(Event *event);	
-		
+		void setPropWidth(Number width);
+				
 		void set(Texture *texture);
 		Texture* get();
 		
@@ -333,7 +392,7 @@ class PropSheet : public UIElement {
 
 class ShaderOptionsSheet : public PropSheet {
 	public:
-		ShaderOptionsSheet(String title, String name);
+		ShaderOptionsSheet();
 		~ShaderOptionsSheet();
 		
 		void handleEvent(Event *event);
@@ -341,7 +400,7 @@ class ShaderOptionsSheet : public PropSheet {
 		
 		void clearShader();
 		void setOptionsFromParams(std::vector<ProgramParam> &params);
-		void setShader(Shader *shader, Material *material);
+		void setShader(Shader *shader, Material *material, ShaderBinding *binding);
 				
 	private:
 		Shader *shader;
@@ -359,7 +418,7 @@ class ShaderTexturesSheet : public PropSheet {
 		void Update();
 		
 		void clearShader();
-		void setShader(Shader *shader, Material *material);
+		void setShader(Shader *shader, Material *material, ShaderBinding *binding);
 				
 	private:
 		Shader *shader;
@@ -387,6 +446,67 @@ class EntitySheet : public PropSheet {
 		ComboProp *blendingProp;
 };
 
+class ShaderPassesSheet : public PropSheet {
+	public:
+		ShaderPassesSheet();
+		~ShaderPassesSheet();
+		void handleEvent(Event *event);			
+		void refreshPasses();
+		
+		void Update();
+		
+		void setMaterial(Material *material);
+
+		ShaderBinding *binding;
+		Material *material;
+
+		ShaderPassProp *selectedProp;
+
+		UIButton *addButton;		
+		int removeIndex;		
+};
+
+class TargetBindingsSheet : public PropSheet {
+	public:
+		TargetBindingsSheet();
+		~TargetBindingsSheet();
+		void handleEvent(Event *event);				
+		void setShader(Shader *shader, Material *material, ShaderBinding *binding);
+		
+		void Update();
+		
+		void refreshTargets();
+		
+		ShaderBinding *binding;
+		Material *material;
+		Shader *shader;
+		int shaderIndex;
+		
+		UIButton *addButton;		
+		RenderTargetBinding *bindingToRemove;
+
+};
+
+class RenderTargetsSheet : public PropSheet {
+	public:
+		RenderTargetsSheet();
+		~RenderTargetsSheet();
+		void Update();
+		void handleEvent(Event *event);		
+		
+		void refreshTargets();
+		
+		ShaderBinding *binding;
+		Material *material;
+		Material *lastMaterial;
+		
+		Number normTextureWidth;
+		Number normTextureHeight;
+		
+		UIButton *addButton;		
+		int removeIndex;
+};
+
 class EntityPropSheet : public PropSheet {
 	public:
 		EntityPropSheet();		

BIN
IDE/Contents/Resources/Images/PostPreview/oranges.png


BIN
IDE/Contents/Resources/Images/new_screenshader.png


BIN
IDE/Contents/Resources/Images/screenshader_icon.png


+ 1 - 1
IDE/Contents/Source/PolycodeIDEApp.cpp

@@ -50,7 +50,7 @@ PolycodeIDEApp::PolycodeIDEApp(PolycodeView *view) : EventDispatcher() {
 	CoreServices::getInstance()->getResourceManager()->addDirResource("default");	
 
 	CoreServices::getInstance()->getResourceManager()->addArchive("hdr.pak");
-	CoreServices::getInstance()->getResourceManager()->addDirResource("hdr");	
+	CoreServices::getInstance()->getResourceManager()->addDirResource("hdr");
 
 
 	CoreServices::getInstance()->getResourceManager()->addArchive("api.pak");

+ 560 - 66
IDE/Contents/Source/PolycodeMaterialEditor.cpp

@@ -28,6 +28,164 @@ extern UIColorPicker *globalColorPicker;
 extern UIGlobalMenu *globalMenu;
 extern PolycodeFrame *globalFrame;
 
+PostEditorPane::PostEditorPane() : UIElement() {
+	currentMaterial = NULL;
+	
+	bottomElement = new UIElement();
+	
+	headerBgBottom = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
+	bottomElement->addChild(headerBgBottom);
+	headerBgBottom->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+	headerBgBottom->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));	
+	
+	propList = new PropList("POST EFFECT EDITOR");
+	bottomElement->addChild(propList);
+	
+	baseProps = new PropSheet("EFFECT OPTIONS", "");
+	propList->addPropSheet(baseProps);
+
+	nameProp = new StringProp("Name");
+	baseProps->addProp(nameProp);
+	nameProp->addEventListener(this, Event::CHANGE_EVENT);
+	
+	fp16Prop = new BoolProp("HDR targets");
+	fp16Prop->set(false);
+	baseProps->addProp(fp16Prop);
+	fp16Prop->addEventListener(this, Event::CHANGE_EVENT);
+		
+	baseProps->propHeight = 100;	
+
+	targetsProps = new RenderTargetsSheet();
+	propList->addPropSheet(targetsProps);
+		
+	passProps = new ShaderPassesSheet();
+	propList->addPropSheet(passProps);
+	passProps->addEventListener(this, Event::CHANGE_EVENT);
+	passProps->addEventListener(this, Event::REMOVE_EVENT);
+	passProps->addEventListener(this, Event::SELECT_EVENT);
+
+	optionsPropList = new PropList("SHADER PASS OPTIONS");
+	bottomElement->addChild(optionsPropList);
+	optionsPropList->setPosition(400, 0);
+
+	targetBindingProps = new TargetBindingsSheet();
+	optionsPropList->addPropSheet(targetBindingProps);
+	targetBindingProps->addEventListener(this, Event::CHANGE_EVENT);
+		
+	shaderTextureSheet = new ShaderTexturesSheet();
+	optionsPropList->addPropSheet(shaderTextureSheet);
+
+	shaderOptionsSheet = new ShaderOptionsSheet();
+	optionsPropList->addPropSheet(shaderOptionsSheet);
+
+	
+	topElement = new UIElement();	
+	postPreview = new PostPreviewBox();
+	topElement->addChild(postPreview);
+	postPreview->setPosition(0, 0);
+		
+	mainSizer = new UIVSizer(100, 100, 300, true);
+	mainSizer->setPosition(0, 0);
+	mainSizer->addTopChild(topElement);
+	mainSizer->addBottomChild(bottomElement);
+	mainSizer->addEventListener(this, UIEvent::CHANGE_EVENT);
+	addChild(mainSizer);
+	enabled = false;
+		
+}
+
+PostEditorPane::~PostEditorPane() {
+
+}
+
+void PostEditorPane::Resize(Number width, Number height) {
+	mainSizer->Resize(width, height);
+	headerBgBottom->setShapeSize(width, 30);	
+	propList->Resize(width/2.0, height- mainSizer->getMainHeight());
+	
+	propList->updateProps();
+	optionsPropList->Resize(width/2.0, height- mainSizer->getMainHeight());
+	optionsPropList->setPosition(floor(width/2.0), optionsPropList->getPosition().y);
+	optionsPropList->updateProps();	
+	UIElement::Resize(width, height);
+	adjustPreview();
+}
+
+void PostEditorPane::adjustPreview() {
+	targetsProps->normTextureWidth = getWidth();
+	targetsProps->normTextureHeight = mainSizer->getMainHeight()-30;
+	postPreview->Resize(getWidth(), mainSizer->getMainHeight());
+}
+
+
+void PostEditorPane::setMaterial(Material *material) {
+	enabled = true;
+	currentMaterial = material;		
+		
+	nameProp->set(material->getName());
+	
+	if(currentMaterial->fp16RenderTargets) {
+		fp16Prop->set(true);
+	} else {
+		fp16Prop->set(false);
+	}
+	
+	targetsProps->material = material;
+	passProps->setMaterial(material);	
+	postPreview->setMaterial(material);
+	
+	optionsPropList->visible = false;
+	optionsPropList->enabled = false;
+	
+	adjustPreview();
+	
+	for(int i=0; i < currentMaterial->getNumShaderRenderTargets(); i++) {
+		ShaderRenderTarget *target = currentMaterial->getShaderRenderTarget(i);
+		if(target->sizeMode == ShaderRenderTarget::SIZE_MODE_NORMALIZED) {
+			target->normalizedWidth = targetsProps->normTextureWidth;
+			target->normalizedHeight = targetsProps->normTextureHeight;
+			currentMaterial->recreateRenderTarget(target);
+		}
+	}
+				
+}
+
+void PostEditorPane::handleEvent(Event *event) {
+	if(event->getDispatcher() == nameProp) {
+		currentMaterial->setName(nameProp->get());
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);					
+	} else if(event->getDispatcher() == mainSizer && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+			propList->Resize(propList->getWidth(), height-mainSizer->getMainHeight());
+			propList->updateProps();
+			adjustPreview();
+	} else if(event->getDispatcher() == passProps || event->getDispatcher() == targetBindingProps) {
+		if(event->getEventCode() == Event::REMOVE_EVENT) {
+				optionsPropList->visible = false;
+				optionsPropList->enabled = false;	
+		} else if(event->getEventCode() == Event::CHANGE_EVENT) {
+			postPreview->clearMaterial();
+			postPreview->setMaterial(currentMaterial);
+		} else if(event->getEventCode() == Event::SELECT_EVENT) {
+			if(passProps->selectedProp) {
+				int shaderIndex = passProps->selectedProp->shaderIndex;
+				Material *material = passProps->selectedProp->material;
+				ShaderBinding *binding = material->getShaderBinding(shaderIndex);
+				targetBindingProps->setShader(currentMaterial->getShader(shaderIndex), material, binding);
+				shaderTextureSheet->setShader(currentMaterial->getShader(shaderIndex), material, binding);
+				shaderOptionsSheet->setShader(currentMaterial->getShader(shaderIndex), material, binding);		
+				optionsPropList->visible = true;
+				optionsPropList->enabled = true;	
+				
+			}
+		}
+	} else if(event->getDispatcher() == fp16Prop && event->getEventCode() == Event::CHANGE_EVENT) {
+		currentMaterial->fp16RenderTargets = fp16Prop->get();
+		currentMaterial->recreateRenderTargets();
+	}
+}
+
+
+
 CubemapEditorPane::CubemapEditorPane() : UIElement() {
 	currentCubemap = NULL;
 
@@ -355,6 +513,165 @@ void ShaderEditorPane::Resize(Number width, Number height) {
 	propList->updateProps();
 }
 
+PostPreviewBox::PostPreviewBox() : UIElement() {
+
+	headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
+	addChild(headerBg);
+	headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+	headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));	
+
+	ScreenLabel *label = new ScreenLabel("POST PREVIEW", 18, "section", Label::ANTIALIAS_FULL);
+	label->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderFontColor"));
+	addChild(label);
+	label->setPosition(10, 3);
+
+	currentMaterial = NULL;
+	previewScene = new Scene(true);	
+	
+	renderTexture = new SceneRenderTexture(previewScene, previewScene->getDefaultCamera(), 512, 512, true);
+	
+
+	CoreServices::getInstance()->getRenderer()->setClippingPlanes(0.1, 100.0);
+
+	previewScene->clearColor.setColor(0.0, 0.0, 0.0, 1.0);	
+	previewScene->ambientColor.setColor(0.0, 0.0, 0.0, 1.0);
+
+	mainLight = new SceneLight(SceneLight::AREA_LIGHT, previewScene, 90.0);
+	mainLight->setPosition(-6,6,6);
+	previewScene->addLight(mainLight);
+
+	secondLight = new SceneLight(SceneLight::AREA_LIGHT, previewScene, 90.0);
+	secondLight->setPosition(6,-6,6);
+	previewScene->addLight(secondLight);
+
+	previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_PLANE, 10.0, 10.0);
+	previewScene->addChild(previewPrimitive);
+	previewPrimitive->setMaterialByName("DefaultHDR");
+	previewPrimitive->setColorInt(198, 192, 166, 255);	
+	
+	previewPrimitive->getMaterial()->getShaderBinding(0)->getLocalParamByName("shininess")->setNumber(90);
+
+	previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_TORUS, 0.9, 0.45, 26, 16);
+	previewScene->addChild(previewPrimitive);
+	previewPrimitive->setMaterialByName("DefaultHDR");
+	previewPrimitive->setColorInt(255, 0, 0, 255);	
+	previewPrimitive->setPosition(1.5, 0.4, 1.0);
+
+	previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_SPHERE, 1.0, 16, 16);
+	previewScene->addChild(previewPrimitive);
+	previewPrimitive->setMaterialByName("DefaultHDR");
+	previewPrimitive->setColorInt(0, 255, 0, 255);
+	previewPrimitive->setPosition(-0.8, 1.0, 0.8);
+
+	previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 2,  2, 2);
+	previewPrimitive->getMesh()->calculateNormals(false);	
+	previewScene->addChild(previewPrimitive);
+	previewPrimitive->setMaterialByName("DefaultHDR");
+	previewPrimitive->setColorInt(0, 0, 255, 255);
+	previewPrimitive->rotation.yaw = 20;
+	previewPrimitive->setPosition(1.0, 1.0, -2.5);
+	
+	previewScene->getDefaultCamera()->setPosition(0,3.0,5);
+	previewScene->getDefaultCamera()->lookAt(Vector3(0.0, 0.5, 0.0));
+
+	
+	previewBase = new ScreenEntity();
+	previewBase->processInputEvents = true;
+	previewBase->setPosition(0, 30);
+	addChild(previewBase);
+	
+	previewShape = new ScreenShape(ScreenShape::SHAPE_RECT, 256, 256);
+	previewShape->setPositionMode(ScreenEntity::POSITION_TOPLEFT);	
+	previewShape->setTexture(renderTexture->getTargetTexture());
+//	previewShape->strokeEnabled = true;
+//	previewShape->strokeColor = Color(1.0, 1.0, 1.0, 0.2);
+//	previewShape->setStrokeWidth(1.0);
+	previewBase->addChild(previewShape);
+
+	spinValue = 0.0;
+	
+	rotateCheckBox = new UICheckBox("Auto-rotate", false);
+	addChild(rotateCheckBox);
+	rotateCheckBox->setPosition(150, 2);
+
+	label = new ScreenLabel("EXPOSURE", 18, "section", Label::ANTIALIAS_FULL);
+	label->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderFontColor"));
+	addChild(label);
+	label->setPosition(270, 3);
+	
+	cameraExposureInput = new UITextInput(false, 40, 12);
+	addChild(cameraExposureInput);
+	cameraExposureInput->setPosition(370, 2);
+	cameraExposureInput->setText(String::NumberToString(previewScene->getDefaultCamera()->getExposureLevel()));	
+	cameraExposureInput->addEventListener(this, UIEvent::CHANGE_EVENT);
+
+	label = new ScreenLabel("LIGHT INT.", 18, "section", Label::ANTIALIAS_FULL);
+	label->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderFontColor"));
+	addChild(label);
+	label->setPosition(430, 3);
+
+	lightStrength = new UITextInput(false, 40, 12);
+	addChild(lightStrength);
+	lightStrength->setPosition(530, 2);
+	lightStrength->setText("90.0");
+	lightStrength->addEventListener(this, UIEvent::CHANGE_EVENT);
+	
+}
+
+void PostPreviewBox::Update() {
+	spinValue += CoreServices::getInstance()->getCore()->getElapsed();
+	
+	if(rotateCheckBox->isChecked()) {
+		previewScene->getDefaultCamera()->setPosition(sin(spinValue) * 5.0,3.0, cos(spinValue) * 5.0);
+	} else {
+		previewScene->getDefaultCamera()->setPosition(0,3.0,5);
+	}	
+	previewScene->getDefaultCamera()->lookAt(Vector3(0.0, 0.5, 0.0));		
+
+}
+
+void PostPreviewBox::Resize(Number width, Number height) {
+	previewShape->setShapeSize(width, height-30);
+	headerBg->setShapeSize(width, 30);
+	
+	int textureWidth = (int)width;
+	int textureHeight = (int) (height-30);
+	renderTexture->resizeRenderTexture(textureWidth, textureHeight);
+	previewShape->setTexture(renderTexture->getTargetTexture());	
+	UIElement::Resize(width, height);
+	
+	if(currentMaterial) {
+		for(int i=0; i < currentMaterial->getNumShaderRenderTargets(); i++) {
+			currentMaterial->getShaderRenderTarget(i)->normalizedWidth = textureWidth;
+			currentMaterial->getShaderRenderTarget(i)->normalizedHeight = textureHeight;
+			currentMaterial->recreateRenderTarget(currentMaterial->getShaderRenderTarget(i));
+		}
+	}
+}
+
+PostPreviewBox::~PostPreviewBox() {
+
+}
+
+void PostPreviewBox::setMaterial(Material *material) {
+	previewScene->getDefaultCamera()->setPostFilter(material);
+}
+
+void PostPreviewBox::clearMaterial() {
+	previewScene->getDefaultCamera()->removePostFilter();
+}
+
+void PostPreviewBox::handleEvent(Event *event) {
+	if(event->getDispatcher() == cameraExposureInput && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+		Number newExposure = atof(cameraExposureInput->getText().c_str());
+		previewScene->getDefaultCamera()->setExposureLevel(newExposure);
+	} else if(event->getDispatcher() == lightStrength && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+		Number newStrength = atof(lightStrength->getText().c_str());
+		mainLight->setIntensity(newStrength);
+		secondLight->setIntensity(newStrength);		
+	}
+}
+
 MaterialPreviewBox::MaterialPreviewBox() : UIElement() {
 	currentMaterial = NULL;
 	previewScene = new Scene(true);	
@@ -522,7 +839,7 @@ MaterialEditorPane::MaterialEditorPane() : UIElement() {
 	propList->addPropSheet(shaderTextureSheet);			
 	shaderTextureSheet->addEventListener(this, Event::CHANGE_EVENT);
 		
-	shaderOptionsSheet = new ShaderOptionsSheet("SHADER OPTIONS", "shader_options");
+	shaderOptionsSheet = new ShaderOptionsSheet();
 	propList->addPropSheet(shaderOptionsSheet);
 	shaderOptionsSheet->addEventListener(this, Event::CHANGE_EVENT);
 		
@@ -564,8 +881,8 @@ void MaterialEditorPane::Resize(Number width, Number height) {
 void MaterialEditorPane::handleEvent(Event *event) {
 
 	if(event->getDispatcher() == currentMaterial) {
-		shaderTextureSheet->setShader(currentMaterial->getShader(0), currentMaterial);
-		shaderOptionsSheet->setShader(currentMaterial->getShader(0), currentMaterial);		
+		shaderTextureSheet->setShader(currentMaterial->getShader(0), currentMaterial, currentMaterial->getShaderBinding(0));
+		shaderOptionsSheet->setShader(currentMaterial->getShader(0), currentMaterial, currentMaterial->getShaderBinding(0));		
 	}
 
 	if(event->getDispatcher() == shaderTextureSheet || event->getDispatcher() == shaderOptionsSheet) {
@@ -595,8 +912,8 @@ void MaterialEditorPane::handleEvent(Event *event) {
 				materialPreview->setMaterial(currentMaterial);					
 			}
 			
-			shaderTextureSheet->setShader(selectedShader, currentMaterial);
-			shaderOptionsSheet->setShader(selectedShader, currentMaterial);
+			shaderTextureSheet->setShader(selectedShader, currentMaterial, currentMaterial->getShaderBinding(0));
+			shaderOptionsSheet->setShader(selectedShader, currentMaterial, currentMaterial->getShaderBinding(0));
 		}
 		
 		if(!changingMaterial) {
@@ -656,10 +973,12 @@ MaterialMainWindow::MaterialMainWindow() : UIElement() {
 	materialPane = new MaterialEditorPane();
 	shaderPane = new ShaderEditorPane();
 	cubemapPane = new CubemapEditorPane();
+	postPane = new PostEditorPane();
 		
 	addChild(materialPane);
 	addChild(shaderPane);	
 	addChild(cubemapPane);
+	addChild(postPane);	
 	enableScissor = true;
 }
 	
@@ -668,7 +987,8 @@ void MaterialMainWindow::Resize(Number width, Number height) {
 	scissorBox.setRect(pos.x,pos.y,width, height);
 	materialPane->Resize(width, height);
 	shaderPane->Resize(width, height);
-	cubemapPane->Resize(width, height);	
+	cubemapPane->Resize(width, height);
+	postPane->Resize(width, height);
 }
 
 MaterialBrowser::MaterialBrowser() : UIElement() {
@@ -680,7 +1000,7 @@ MaterialBrowser::MaterialBrowser() : UIElement() {
 	shadersNode = treeContainer->getRootNode()->addTreeChild("Images/shader_icon.png", "Shaders", NULL);
 	materialsNode = treeContainer->getRootNode()->addTreeChild("Images/material_icon.png", "Materials", NULL);
 	cubemapsNode = treeContainer->getRootNode()->addTreeChild("Images/cubemap_icon.png", "Cubemaps", NULL);
-	postEffectsNode = treeContainer->getRootNode()->addTreeChild("folder.png", "Post Effects", NULL);
+	postEffectsNode = treeContainer->getRootNode()->addTreeChild("Images/screenshader_icon.png", "Post Effects", NULL);
 				
 	addChild(treeContainer);		
 	selectedData = NULL;
@@ -701,11 +1021,22 @@ MaterialBrowser::MaterialBrowser() : UIElement() {
 	newCubemapButton = new UIImageButton("Images/new_cubemap.png");
 	addChild(newCubemapButton);
 	newCubemapButton->setPosition(59,4);
+		
+	newPostButton = new UIImageButton("Images/new_screenshader.png");
+	addChild(newPostButton);
+	newPostButton->setPosition(86,4);
+
+	removeButton = new UIImageButton("Images/remove_icon.png");
+	addChild(removeButton);
+	removeButton->setPosition(0,4);
 	
 	selectedNode = NULL;
 
 }
 
+void MaterialBrowser::removeSelected() {
+	selectedNode->getParent()->removeTreeChild(selectedNode);
+}
 
 void MaterialBrowser::handleEvent(Event *event) {
 
@@ -716,8 +1047,7 @@ void MaterialBrowser::handleEvent(Event *event) {
 			selectedData =  data;
 			dispatchEvent(new Event(), Event::CHANGE_EVENT);
 		}
-	}
-	
+	}	
 	ScreenEntity::handleEvent(event);
 }
 
@@ -740,6 +1070,12 @@ UITree *MaterialBrowser::addCubemap(Cubemap *cubemap) {
 	return cubemapsNode->addTreeChild("cubemap_icon.png", cubemap->getResourceName(), (void*)data);	
 }
 
+UITree *MaterialBrowser::addPostMaterial(Material *material) {
+	MaterialBrowserData *data = new MaterialBrowserData();
+	data->postMaterial = material;
+	return postEffectsNode->addTreeChild("screenshader_icon.png", material->getName(), (void*)data);
+}
+
 MaterialBrowser::~MaterialBrowser() {
 
 }
@@ -748,6 +1084,7 @@ void MaterialBrowser::Resize(Number width, Number height) {
 	treeContainer->Resize(width, height-30);
 	treeContainer->setPosition(0, 30);	
 	headerBg->setShapeSize(width, 30);	
+	removeButton->setPosition(width - 24, 8);
 }
 
 PolycodeMaterialEditor::PolycodeMaterialEditor() : PolycodeEditor(true){
@@ -784,10 +1121,24 @@ bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
 	}	
 
 	
-	materials = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(filePath.fullPath);	
+	std::vector<Material*> mats = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(filePath.fullPath);
+	
+	materials.clear();
+	for(int i=0; i < mats.size(); i++) {
+		if(mats[i]->screenMaterial) {
+			postMaterials.push_back(mats[i]);
+		} else {
+			materials.push_back(mats[i]);		
+		}
+	}
+	
 	for(int i=0; i < materials.size(); i++) {
 		materialBrowser->addMaterial(materials[i]);
 	}
+
+	for(int i=0; i < postMaterials.size(); i++) {
+		materialBrowser->addPostMaterial(postMaterials[i]);
+	}
 	
 	mainWindow = new MaterialMainWindow();
 	mainSizer->addLeftChild(mainWindow);
@@ -795,13 +1146,16 @@ bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
 	mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
 	mainWindow->shaderPane->addEventListener(this, Event::CHANGE_EVENT);
 	mainWindow->cubemapPane->addEventListener(this, Event::CHANGE_EVENT);
-		
+	mainWindow->postPane->addEventListener(this, Event::CHANGE_EVENT);
+			
 	mainWindow->shaderPane->parentProject = parentProject;
 	
 	materialBrowser->newMaterialButton->addEventListener(this, UIEvent::CLICK_EVENT);
 	materialBrowser->newShaderButton->addEventListener(this, UIEvent::CLICK_EVENT);
 	materialBrowser->newCubemapButton->addEventListener(this, UIEvent::CLICK_EVENT);
-			
+	materialBrowser->newPostButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	materialBrowser->removeButton->addEventListener(this, UIEvent::CLICK_EVENT);
+					
 	mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
 	
 	PolycodeEditor::openFile(filePath);
@@ -838,6 +1192,132 @@ String PolycodeMaterialEditor::createStringValue(unsigned int type, void *value)
 	return retString;
 }
 
+void PolycodeMaterialEditor::saveMaterials(ObjectEntry *materialsEntry, std::vector<Material*> materials) {
+	for(int i=0; i < materials.size(); i++) {
+		Material *material = materials[i];				
+		
+		ObjectEntry *materialEntry = materialsEntry->addChild("material");
+		materialEntry->addChild("name", material->getName());
+		materialEntry->addChild("blendingMode", material->blendingMode);
+		
+		if(material->screenMaterial) {
+			materialEntry->addChild("screen", true);
+		}
+		
+		if(material->screenMaterial) {		
+		if(material->getNumShaderRenderTargets() > 0) {		
+			ObjectEntry *targetsEntry = materialEntry->addChild("rendertargets");
+			if(material->fp16RenderTargets) {
+				targetsEntry->addChild("type", String("rgba_fp16"));
+			} else {
+				targetsEntry->addChild("type", String("rgba"));			
+			}
+			
+			for(int j=0; j < material->getNumShaderRenderTargets(); j++) {
+				ObjectEntry *targetEntry = targetsEntry->addChild("rendertarget");
+				
+				ShaderRenderTarget *target = material->getShaderRenderTarget(j);
+				
+				targetEntry->addChild("id", target->id);
+				if(target->sizeMode == ShaderRenderTarget::SIZE_MODE_NORMALIZED) {
+					targetEntry->addChild("sizeMode", "normalized");
+				} else {
+					targetEntry->addChild("sizeMode", "pixels");
+				}
+				
+				targetEntry->addChild("width", target->width);
+				targetEntry->addChild("height", target->height);								
+			}
+			
+			}
+		}
+		
+		if(material->getNumShaders() > 0) {
+			for(int s=0; s < material->getNumShaders(); s++) { 
+				Shader *shader = material->getShader(s);
+				
+				ObjectEntry *shaderEntry = materialEntry->addChild("shader");
+				shaderEntry->addChild("name", shader->getName());		
+				ObjectEntry *texturesEntry = shaderEntry->addChild("textures");
+				
+				ShaderBinding *shaderBinding = material->getShaderBinding(s);
+				
+				if(material->screenMaterial) {
+					if(shaderBinding->getNumRenderTargetBindings() > 0) {
+						ObjectEntry *targetsEntry = shaderEntry->addChild("targettextures");
+						for(int j=0; j < shaderBinding->getNumRenderTargetBindings(); j++) {
+							RenderTargetBinding *binding = shaderBinding->getRenderTargetBinding(j);
+							ObjectEntry *targetEntry = targetsEntry->addChild("targettexture");
+							switch(binding->mode) {
+								case RenderTargetBinding::MODE_IN:
+									targetEntry->addChild("mode", "in");								
+									targetEntry->addChild("name", binding->name);
+									targetEntry->addChild("id", binding->id);									
+								break;
+								case RenderTargetBinding::MODE_OUT:
+									targetEntry->addChild("mode", "out");								
+									targetEntry->addChild("name", binding->name);
+									targetEntry->addChild("id", binding->id);								
+								break;
+								case RenderTargetBinding::MODE_COLOR:
+									targetEntry->addChild("mode", "color");
+									targetEntry->addChild("name", binding->name);		
+								break;
+								case RenderTargetBinding::MODE_DEPTH:
+									targetEntry->addChild("mode", "depth");
+									targetEntry->addChild("name", binding->name);
+								break;																								
+							}
+						}
+					}
+				}
+				
+				for(int j=0; j < shader->expectedTextures.size(); j++) {
+					Texture *texture = shaderBinding->getTexture(shader->expectedTextures[j]);
+					
+					bool inRenderBinding = false;
+					
+					for(int b=0; b < shaderBinding->getNumRenderTargetBindings(); b++) {
+						RenderTargetBinding *_binding = shaderBinding->getRenderTargetBinding(b);
+						if(_binding->name == shader->expectedTextures[j]) {
+							inRenderBinding = true;
+						}
+					}
+					
+					if(texture && !inRenderBinding) {
+						String texturePath = texture->getResourcePath();
+						texturePath = texturePath.replace(parentProject->getRootFolder()+"/", "");				
+						ObjectEntry *textureEntry = texturesEntry->addChild("texture", texturePath);
+						textureEntry->addChild("name", shader->expectedTextures[j]);
+					}
+				}
+				
+				for(int j=0; j < shader->expectedCubemaps.size(); j++) {
+					Cubemap *cubemap = shaderBinding->getCubemap(shader->expectedCubemaps[j]);
+					if(cubemap) {
+						String cubemapName = cubemap->getResourceName();
+						ObjectEntry *cubemapEntry = texturesEntry->addChild("cubemap", cubemapName);
+						cubemapEntry->addChild("name", shader->expectedCubemaps[j]);
+					}
+				}
+				
+				
+				if(shader->expectedParams.size() > 0 || shader->expectedParams.size() > 0) {
+					ObjectEntry *paramsEntry = shaderEntry->addChild("params");
+					
+					for(int j=0; j < shader->expectedParams.size(); j++) {
+						if(shaderBinding->getLocalParamByName(shader->expectedParams[j].name)) {
+							ObjectEntry *paramEntry = paramsEntry->addChild("param");
+							paramEntry->addChild("name", shader->expectedParams[j].name);
+							paramEntry->addChild("value", createStringValue(shader->expectedParams[j].type, shaderBinding->getLocalParamByName(shader->expectedParams[j].name)->data));
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
 void PolycodeMaterialEditor::saveFile() {
 
 	Object fileData;
@@ -878,58 +1358,9 @@ void PolycodeMaterialEditor::saveFile() {
 	}
 	
 	ObjectEntry *materialsEntry = fileData.root.addChild("materials");
-	
-	for(int i=0; i < materials.size(); i++) {
-		Material *material = materials[i];				
-		
-		ObjectEntry *materialEntry = materialsEntry->addChild("material");
-		materialEntry->addChild("name", material->getName());
-		materialEntry->addChild("blendingMode", material->blendingMode);
-		
-		if(material->getShader(0) && material->getShaderBinding(0)) {
-				
-		Shader *shader = material->getShader(0);
-		
-		ObjectEntry *shaderEntry = materialEntry->addChild("shader");
-		shaderEntry->addChild("name", shader->getName());		
-		ObjectEntry *texturesEntry = shaderEntry->addChild("textures");
-		
-		ShaderBinding *shaderBinding = material->getShaderBinding(0);
-		
-		for(int j=0; j < shader->expectedTextures.size(); j++) {
-			Texture *texture = shaderBinding->getTexture(shader->expectedTextures[j]);
-			if(texture) {
-				String texturePath = texture->getResourcePath();
-				texturePath = texturePath.replace(parentProject->getRootFolder()+"/", "");				
-				ObjectEntry *textureEntry = texturesEntry->addChild("texture", texturePath);
-				textureEntry->addChild("name", shader->expectedTextures[j]);
-			}
-		}
-
-		for(int j=0; j < shader->expectedCubemaps.size(); j++) {
-			Cubemap *cubemap = shaderBinding->getCubemap(shader->expectedCubemaps[j]);
-			if(cubemap) {
-				String cubemapName = cubemap->getResourceName();
-				ObjectEntry *cubemapEntry = texturesEntry->addChild("cubemap", cubemapName);
-				cubemapEntry->addChild("name", shader->expectedCubemaps[j]);
-			}
-		}
-
-
-		if(shader->expectedParams.size() > 0 || shader->expectedParams.size() > 0) {
-			ObjectEntry *paramsEntry = shaderEntry->addChild("params");
+	saveMaterials(materialsEntry, materials);
+	saveMaterials(materialsEntry, postMaterials);
 			
-			for(int j=0; j < shader->expectedParams.size(); j++) {
-				if(shaderBinding->getLocalParamByName(shader->expectedParams[j].name)) {
-					ObjectEntry *paramEntry = paramsEntry->addChild("param");
-					paramEntry->addChild("name", shader->expectedParams[j].name);
-					paramEntry->addChild("value", createStringValue(shader->expectedParams[j].type, shaderBinding->getLocalParamByName(shader->expectedParams[j].name)->data));
-				}
-			}
-		}
-		}
-	}
-	
 	fileData.saveToXML(filePath);
 	setHasChanges(false);
 }
@@ -957,7 +1388,22 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 		setHasChanges(true);
 	}
 
-		
+	if(event->getDispatcher() == mainWindow->postPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
+		if(selectedMaterialNode && mainWindow->postPane->currentMaterial) {
+			selectedMaterialNode->setLabelText(mainWindow->postPane->currentMaterial->getName());
+		}
+		setHasChanges(true);
+	}
+
+	if(event->getDispatcher() == materialBrowser->newPostButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
+	
+		Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("PostEffect"+String::IntToString(postMaterials.size()), "PassThrough");
+			newMaterial->screenMaterial = true;
+			materialBrowser->addPostMaterial(newMaterial)->setSelected();
+			postMaterials.push_back(newMaterial);
+			setHasChanges(true);			
+	}	
+
 	if(event->getDispatcher() == materialBrowser->newMaterialButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
 		Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("Untitled", "DefaultShader");
 			materialBrowser->addMaterial(newMaterial)->setSelected();
@@ -966,7 +1412,7 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 	}	
 
 	if(event->getDispatcher() == materialBrowser->newShaderButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
-			Shader *newShader = CoreServices::getInstance()->getMaterialManager()->createShader("glsl", "Untitled", "Unlit.vert", "Unlit.frag", false);
+			Shader *newShader = CoreServices::getInstance()->getMaterialManager()->createShader("glsl", "Untitled", "default/Unlit.vert", "default/Unlit.frag", false);
 			if(newShader) {
 				materialBrowser->addShader(newShader);
 				shaders.push_back(newShader);
@@ -992,6 +1438,50 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 		CoreServices::getInstance()->getResourceManager()->addResource(cubemap);
 	}	
 		
+	if(event->getDispatcher() == materialBrowser->removeButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
+
+				mainWindow->materialPane->enabled = false;
+				mainWindow->shaderPane->enabled = false;
+				mainWindow->cubemapPane->enabled = false;
+				mainWindow->postPane->enabled = false;
+				
+				if(materialBrowser->selectedData) {
+				if(materialBrowser->selectedData->material) {
+					for(int i=0; i < materials.size(); i++) {
+						if(materials[i] == materialBrowser->selectedData->material) {
+							materials.erase(materials.begin()+i);
+							materialBrowser->removeSelected();
+							break;							
+						}
+					}
+				} else if(materialBrowser->selectedData->shader) {
+					for(int i=0; i < shaders.size(); i++) {
+						if(shaders[i] == materialBrowser->selectedData->shader) {
+							shaders.erase(shaders.begin()+i);
+							materialBrowser->removeSelected();							
+							break;
+						}
+					}				
+				} else if(materialBrowser->selectedData->cubemap) {
+					for(int i=0; i < cubemaps.size(); i++) {
+						if(cubemaps[i] == materialBrowser->selectedData->cubemap) {
+							cubemaps.erase(cubemaps.begin()+i);
+							materialBrowser->removeSelected();							
+							break;
+						}
+					}								
+				} else if(materialBrowser->selectedData->postMaterial) {
+					for(int i=0; i < postMaterials.size(); i++) {
+						if(postMaterials[i] == materialBrowser->selectedData->postMaterial) {
+							postMaterials.erase(postMaterials.begin()+i);
+							materialBrowser->removeSelected();							
+							break;
+						}
+					}												
+				}	
+				}			
+		
+	}
 
 	if(event->getDispatcher() == materialBrowser) {
 		if(event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
@@ -999,7 +1489,8 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 				mainWindow->materialPane->enabled = false;
 				mainWindow->shaderPane->enabled = false;
 				mainWindow->cubemapPane->enabled = false;
-												
+				mainWindow->postPane->enabled = false;
+																
 				if(materialBrowser->selectedData->material) {
 					selectedMaterialNode = materialBrowser->selectedNode;				
 					mainWindow->materialPane->setMaterial(materialBrowser->selectedData->material);					
@@ -1009,6 +1500,9 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 				} else if(materialBrowser->selectedData->cubemap) {
 					selectedMaterialNode = materialBrowser->selectedNode;				
 					mainWindow->cubemapPane->setCubemap(materialBrowser->selectedData->cubemap);
+				} else if(materialBrowser->selectedData->postMaterial) {
+					selectedMaterialNode = materialBrowser->selectedNode;				
+					mainWindow->postPane->setMaterial(materialBrowser->selectedData->postMaterial);
 				}
 
 			}			

+ 620 - 20
IDE/Contents/Source/PolycodeProps.cpp

@@ -248,11 +248,13 @@ void PropSheet::setCollapsed(bool val) {
 		if(collapsed) {
 			collapseButton->enabled = false;
 			expandButton->enabled = true;	
-			contents->enabled = false;		
+			contents->enabled = false;	
+			contents->visible = false;	
 		} else {
 			collapseButton->enabled = true;
 			expandButton->enabled = false;				
 			contents->enabled = true;			
+			contents->visible = true;			
 		}
 	}
 	dispatchEvent(new Event(), Event::COMPLETE_EVENT);	
@@ -402,8 +404,8 @@ void Vector2Prop::setPropData(PolycodeEditorPropActionData* data) {
 
 void Vector2Prop::set(Vector2 position) {
 	suppressChangeEvent = true;
-	positionX->setText(String::NumberToString(position.x));
-	positionY->setText(String::NumberToString(position.y));
+	positionX->setText(String::NumberToString(position.x, 5));
+	positionY->setText(String::NumberToString(position.y, 5));
 	suppressChangeEvent = false;	
 }
 
@@ -483,7 +485,9 @@ StringProp::StringProp(String caption) : PropProp(caption, "String") {
 }
 
 void StringProp::setPropWidth(Number width) {
-	stringEntry->Resize(width - propContents->position.x - PROP_PADDING, stringEntry->getHeight());
+	stringEntry->Resize(floor((width - PROP_PADDING) * 0.5), stringEntry->getHeight());	
+	stringEntry->setPosition(width-105-PROP_PADDING-stringEntry->getWidth(), 2);
+	
 }
 
 void StringProp::handleEvent(Event *event) {
@@ -591,7 +595,8 @@ NumberProp::NumberProp(String caption) : PropProp(caption, "Number") {
 }
 
 void NumberProp::setPropWidth(Number width) {
-	numberEntry->Resize(width - propContents->position.x - PROP_PADDING, numberEntry->getHeight());
+	numberEntry->Resize(floor((width - PROP_PADDING) * 0.5), numberEntry->getHeight());	
+	numberEntry->setPosition(width-105-PROP_PADDING-numberEntry->getWidth(), 2);
 }
 
 void NumberProp::setPropData(PolycodeEditorPropActionData* data) {
@@ -615,7 +620,7 @@ void NumberProp::handleEvent(Event *event) {
 
 void NumberProp::set(Number number) {
 	suppressChangeEvent = true;
-	numberEntry->setText(String::NumberToString(number));
+	numberEntry->setText(String::NumberToString(number), 5);
 	suppressChangeEvent = false;	
 }
 
@@ -919,12 +924,17 @@ TextureProp::TextureProp(String caption) : PropProp(caption, "Texture"){
 	
 	textureLabel = new ScreenLabel("", 12, "sans");
 	propContents->addChild(textureLabel);
-	textureLabel->setPosition(60, 32);
-	textureLabel->color.a = 0.4;
+	textureLabel->setPosition(-100, 32);
+	textureLabel->color.a = 0.3;
 		
 	setHeight(60);	
 }
 
+void TextureProp::setPropWidth(Number width) {
+	changeButton->setPosition(width-changeButton->getWidth()-PROP_PADDING-100, 5);
+	previewShape->setPosition(changeButton->getPosition().x-48-10, 1);	
+}
+
 TextureProp::~TextureProp() {
 
 }
@@ -1210,13 +1220,590 @@ void ShapeSheet::Update() {
 	}
 }
 
+ShaderPassProp::ShaderPassProp(Material *material, int shaderIndex) : PropProp("", "ShaderPassProp") {
+	this->material = material;
+	this->shader = material->getShader(shaderIndex);
+	this->shaderIndex = shaderIndex;
+	
+	removeButton = new UIImageButton("Images/remove_icon.png");
+	removeButton->addEventListener(this, UIEvent::CLICK_EVENT);	
+	propContents->addChild(removeButton);
+	removeButton->setPosition(-110, 6);
+	
+	shaderComboBox = new UIComboBox(globalMenu, 100);
+	shaderComboBox->addEventListener(this, UIEvent::CHANGE_EVENT);
+	propContents->addChild(shaderComboBox);
+	
+	int index = 0;
+	MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
+	for(int i=0; i < materialManager->getNumShaders(); i++) {
+		if(materialManager->getShaderByIndex(i)->screenShader) {
+			shaderComboBox->addComboItem(materialManager->getShaderByIndex(i)->getName(), (void*)materialManager->getShaderByIndex(i));			
+			if(shader == materialManager->getShaderByIndex(i)) {
+				shaderComboBox->setSelectedIndex(index);
+			}
+			index++;
+		}
+	}	
+	
+	
+	editButton = new UIButton("Options", 30);
+	editButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	propContents->addChild(editButton);
+	setHeight(30);
+}
+
+ShaderPassProp::~ShaderPassProp() {
+
+}
+		
+void ShaderPassProp::handleEvent(Event *event) {
+	if(event->getDispatcher() == removeButton && event->getEventCode() == UIEvent::CLICK_EVENT) {
+		dispatchEvent(new Event(), Event::REMOVE_EVENT);
+	} else if(event->getDispatcher() == editButton && event->getEventCode() == UIEvent::CLICK_EVENT) {
+		dispatchEvent(new Event(), Event::SELECT_EVENT);		
+	} else if(event->getDispatcher() == shaderComboBox) {
+		Shader *selectedShader = (Shader*)shaderComboBox->getSelectedItem()->data;
+		if(selectedShader) {
+			if(material->getShader(shaderIndex) != selectedShader) {
+				material->removeShader(shaderIndex);				
+				ShaderBinding *newShaderBinding = selectedShader->createBinding();				
+				material->addShaderAtIndex(selectedShader, newShaderBinding, shaderIndex);
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			}
+		}
+	}
+}
+
+void ShaderPassProp::setPropWidth(Number width) {
+	Number adjustedWidth = width-PROP_PADDING-5;
+	shaderComboBox->setPosition(-90, 0);
+	shaderComboBox->Resize(floor(adjustedWidth * 0.75), shaderComboBox->getHeight());
+
+	editButton->setPosition(-90 + shaderComboBox->getWidth() + 5, 0);
+	editButton->Resize(floor(adjustedWidth * 0.25), editButton->getHeight());
+}
+
+TargetBindingProp::TargetBindingProp(Shader *shader, Material *material, ShaderBinding *binding, RenderTargetBinding *targetBinding) : PropProp("", "TargetBindingProp") {
+	this->targetBinding = targetBinding;
+	this->material = material;
+	this->shader = shader;
+	this->binding = binding;
+		
+	removeButton = new UIImageButton("Images/remove_icon.png");
+	removeButton->addEventListener(this, UIEvent::CLICK_EVENT);	
+	propContents->addChild(removeButton);
+	removeButton->setPosition(-110, 6);
+
+	typeComboBox = new UIComboBox(globalMenu, 100);
+	typeComboBox->addComboItem("IN");		
+	typeComboBox->addComboItem("OUT");
+	typeComboBox->addComboItem("COLOR");
+	typeComboBox->addComboItem("DEPTH");		
+	typeComboBox->setSelectedIndex(targetBinding->mode);
+	typeComboBox->addEventListener(this, UIEvent::CHANGE_EVENT);
+	propContents->addChild(typeComboBox);
+
+	targetComboBox = new UIComboBox(globalMenu, 100);	
+	for(int i=0; i < material->getNumShaderRenderTargets(); i++) {
+		ShaderRenderTarget *target = material->getShaderRenderTarget(i);		
+		targetComboBox->addComboItem(target->id, (void*) target);
+		if(targetBinding->texture == target->texture) {
+			targetComboBox->setSelectedIndex(i);
+		}
+	}
+	targetComboBox->addEventListener(this, UIEvent::CHANGE_EVENT);
+	propContents->addChild(targetComboBox);
+	
+	textureComboBox = new UIComboBox(globalMenu, 100);	
+	for(int i=0; i < shader->expectedTextures.size(); i++) {
+		textureComboBox->addComboItem(shader->expectedTextures[i]);
+		if(shader->expectedTextures[i] == targetBinding->name) {
+			textureComboBox->setSelectedIndex(i);
+		}
+	}
+		
+	textureComboBox->addEventListener(this, UIEvent::CHANGE_EVENT);
+	propContents->addChild(textureComboBox);
+	
+	setHeight(30);
+	
+	if(typeComboBox->getSelectedIndex() == 1) {
+		textureComboBox->enabled = false;
+		textureComboBox->visible = false;			
+	} else {
+		textureComboBox->enabled = true;
+		textureComboBox->visible = true;		
+	}		
+
+	if(typeComboBox->getSelectedIndex() == 2 || typeComboBox->getSelectedIndex() == 3) {
+		targetComboBox->enabled = false;
+		targetComboBox->visible = false;
+	} else {
+		targetComboBox->enabled = true;
+		targetComboBox->visible = true;
+	}		
+	
+}
+
+TargetBindingProp::~TargetBindingProp() {
+
+}
+
+void TargetBindingProp::handleEvent(Event *event) {
+	if(event->getDispatcher() == removeButton && event->getEventCode() == UIEvent::CLICK_EVENT) {
+		dispatchEvent(new Event(), Event::REMOVE_EVENT);
+	} else if(event->getDispatcher() == typeComboBox && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+		binding->clearTexture(targetBinding->name);	
+		
+		if(typeComboBox->getSelectedIndex() == 1) {
+			textureComboBox->enabled = false;
+			textureComboBox->visible = false;
+		} else {
+			textureComboBox->enabled = true;
+			textureComboBox->visible = true;
+			binding->addTexture(targetBinding->name, targetBinding->texture);	
+		}		
+		
+		if(typeComboBox->getSelectedIndex() == 2 || typeComboBox->getSelectedIndex() == 3) {
+			targetComboBox->enabled = false;
+			targetComboBox->visible = false;
+		} else {
+			targetComboBox->enabled = true;
+			targetComboBox->visible = true;
+		}	
+		
+		binding->removeRenderTargetBinding(targetBinding);		
+		targetBinding->mode = typeComboBox->getSelectedIndex();		
+		
+		binding->addRenderTargetBinding(targetBinding);		
+		
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+	} else if(event->getDispatcher() == targetComboBox && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+		ShaderRenderTarget *target = (ShaderRenderTarget*)targetComboBox->getSelectedItem()->data;		
+		targetBinding->texture = target->texture;
+		targetBinding->id  = target->id;
+		targetBinding->width = target->width;
+		targetBinding->height = target->height;
+		
+		binding->removeRenderTargetBinding(targetBinding);		
+		binding->addRenderTargetBinding(targetBinding);		
+
+		binding->clearTexture(targetBinding->name);
+		if(targetBinding->mode == RenderTargetBinding::MODE_IN) {
+			binding->addTexture(targetBinding->name, targetBinding->texture);		
+		}
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);		
+	} else if(event->getDispatcher() == textureComboBox && event->getEventCode() == UIEvent::CHANGE_EVENT) {
+		targetBinding->name = textureComboBox->getSelectedItem()->label;
+		
+		binding->removeRenderTargetBinding(targetBinding);		
+		binding->addRenderTargetBinding(targetBinding);		
+
+		binding->clearTexture(targetBinding->name);
+		binding->addTexture(targetBinding->name, targetBinding->texture);
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+	}
+}
+
+void TargetBindingProp::setPropWidth(Number width) {
+	Number size = width-PROP_PADDING-85-15;
+	
+	typeComboBox->setPosition(-90, 0);
+	typeComboBox->Resize(80, typeComboBox->getHeight());
+
+	targetComboBox->setPosition(-90 + 85, 0);
+	targetComboBox->Resize(floor(size*0.5), targetComboBox->getHeight());
+
+	textureComboBox->setPosition(-90 + 85 + targetComboBox->getWidth() + 5, 0);
+	textureComboBox->Resize(floor(size*0.5), textureComboBox->getHeight());
+
+}
+
+RenderTargetProp::RenderTargetProp(ShaderRenderTarget *renderTarget, Material *material) : PropProp("", "RenderTargetProp") {
+
+	this->material = material;
+	this->renderTarget = renderTarget;
+
+	removeButton = new UIImageButton("Images/remove_icon.png");
+	removeButton->addEventListener(this, UIEvent::CLICK_EVENT);	
+	propContents->addChild(removeButton);
+	removeButton->setPosition(-110, 6);
+	
+	nameInput = new UITextInput(false, 20, 12);
+	nameInput->addEventListener(this, UIEvent::CHANGE_EVENT);
+	propContents->addChild(nameInput);
+	nameInput->setText(renderTarget->id);
+	nameInput->setCaretPosition(0);
+	
+	widthInput = new UITextInput(false, 20, 12);
+	widthInput->setNumberOnly(true);
+	widthInput->setText(String::NumberToString(renderTarget->width));
+	propContents->addChild(widthInput);
+	widthInput->setCaretPosition(0);
+	widthInput->addEventListener(this, UIEvent::CHANGE_EVENT);
+		
+	heightInput = new UITextInput(false, 20, 12);
+	heightInput->setNumberOnly(true);
+	heightInput->setText(String::NumberToString(renderTarget->height));	
+	propContents->addChild(heightInput);
+	heightInput->setCaretPosition(0);
+	heightInput->addEventListener(this, UIEvent::CHANGE_EVENT);
+			
+	typeComboBox = new UIComboBox(globalMenu, 100);
+	typeComboBox->addComboItem("Pixels");		
+	typeComboBox->addComboItem("Norm.");
+	typeComboBox->setSelectedIndex(renderTarget->sizeMode);	
+	typeComboBox->addEventListener(this, UIEvent::CHANGE_EVENT);
+	propContents->addChild(typeComboBox);
+	
+	setHeight(30);
+}
+
+void RenderTargetProp::setPropWidth(Number width) {
+	Number quarter = floor((width-PROP_PADDING- (5*3)) * 0.25);
+	nameInput->setPosition(-90, 0);
+	nameInput->Resize(floor(quarter * 1.8), nameInput->getHeight());
+
+	widthInput->setPosition(-90 + 5 + (quarter * 1.8), 0);
+	widthInput->Resize(floor(quarter*0.6), widthInput->getHeight());
+
+	heightInput->setPosition(-90 + 10 + (quarter * 2.4), 0);
+	heightInput->Resize(floor(quarter*0.6), heightInput->getHeight());	
+	
+	typeComboBox->setPosition(-90 + 15 + (quarter*3), 0);
+	typeComboBox->Resize(floor(quarter), typeComboBox->getHeight());
+}
+
+RenderTargetProp::~RenderTargetProp() {
+
+}
+
+void RenderTargetProp::recreateRenderTarget() {
+	material->recreateRenderTarget(renderTarget);
+}
+
+void RenderTargetProp::handleEvent(Event *event) {
+	if(event->getEventType() == "UIEvent") {
+
+		if(event->getDispatcher() == nameInput) {
+			renderTarget->id = nameInput->getText();
+		}
+	
+		if(event->getDispatcher() == typeComboBox) {
+			renderTarget->sizeMode = typeComboBox->getSelectedIndex();
+			recreateRenderTarget();
+		}
+
+		if(event->getDispatcher() == typeComboBox) {
+			renderTarget->sizeMode = typeComboBox->getSelectedIndex();
+			recreateRenderTarget();
+		}
+
+		if(event->getDispatcher() == widthInput) {
+			renderTarget->width =  atof(widthInput->getText().c_str());
+			recreateRenderTarget();
+		}
+
+		if(event->getDispatcher() == heightInput) {
+			renderTarget->height =  atof(heightInput->getText().c_str());
+			recreateRenderTarget();
+		}
+
+		
+		if(event->getDispatcher() == removeButton) {
+			dispatchEvent(new Event(), Event::CANCEL_EVENT);
+		}
+	}
+	
+	PropProp::handleEvent(event);
+}
+
+ShaderPassesSheet::ShaderPassesSheet() : PropSheet("SHADER PASSES", "shaderPasses") {
+	propHeight = 70;
+	addButton = new UIButton("Add Shader Pass", 150);
+	addButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	contents->addChild(addButton);
+	addButton->setPosition(15, 35);
+	
+	customUndoHandler = true;
+	material = NULL;
+	binding = NULL;
+	selectedProp = NULL;
+	
+	removeIndex = -1;
+}
+
+ShaderPassesSheet::~ShaderPassesSheet() {
+
+}
+
+void ShaderPassesSheet::setMaterial(Material *material) {
+	this->material = material;
+	refreshPasses();
+}
+
+void ShaderPassesSheet::refreshPasses() {
+
+	for(int i=0; i < props.size(); i++) {
+		contents->removeChild(props[i]);
+		props[i]->removeAllHandlersForListener(this);
+		delete props[i];
+	}
+	props.clear();
+	propHeight = 0;
+
+	if(!material) {
+		return;
+	}
+
+	for(int i=0; i < material->getNumShaders(); i++) {
+		ShaderPassProp *passProp = new ShaderPassProp(material, i);
+		passProp->addEventListener(this, Event::REMOVE_EVENT);
+		passProp->addEventListener(this, Event::CHANGE_EVENT);		
+		passProp->addEventListener(this, Event::SELECT_EVENT);
+		addProp(passProp);
+		propHeight += 30;	
+	}
+	
+	addButton->setPosition(15, propHeight);	
+	propHeight += 70;	
+
+	dispatchEvent(new Event(), Event::COMPLETE_EVENT);		
+	Resize(width, height);	
+	
+}
+
+void ShaderPassesSheet::Update() {
+	if(removeIndex != -1) {
+		material->removeShader(removeIndex);
+		refreshPasses();
+		removeIndex = -1;			
+	}
+}
+
+void ShaderPassesSheet::handleEvent(Event *event) {
+
+	if(event->getDispatcher() == addButton) {
+	
+		Shader *defaultShader = (Shader*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_SHADER, "PassThrough");
+		if(defaultShader) {	
+			ShaderBinding *newShaderBinding = defaultShader->createBinding();		
+			material->addShader(defaultShader, newShaderBinding);
+		}
+		refreshPasses();
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);		
+	} else {
+		for(int i=0; i < props.size(); i++) {	
+			if(event->getDispatcher() == props[i]) {
+				if(event->getEventCode() == Event::CHANGE_EVENT) {
+					dispatchEvent(new Event(), Event::CHANGE_EVENT);
+					selectedProp = (ShaderPassProp*)props[i];
+					dispatchEvent(new Event(), Event::SELECT_EVENT);					
+				} else if(event->getEventCode() == Event::SELECT_EVENT) {
+					selectedProp = (ShaderPassProp*)props[i];
+					dispatchEvent(new Event(), Event::SELECT_EVENT);				
+				} else if(event->getEventCode() == Event::REMOVE_EVENT) {
+					removeIndex = i;
+					dispatchEvent(new Event(), Event::REMOVE_EVENT);					
+				}
+			}
+		}
+	}
+
+	PropSheet::handleEvent(event);
+}
+
+TargetBindingsSheet::TargetBindingsSheet() : PropSheet("TEXTURE BINDINGS", "targetBindings") {
+	propHeight = 70;
+	addButton = new UIButton("Add Render Target", 150);
+	addButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	contents->addChild(addButton);
+	addButton->setPosition(15, 35);	
+	customUndoHandler = true;	
+	material = NULL;
+	binding = NULL;	
+	bindingToRemove = NULL;
+}
+
+TargetBindingsSheet::~TargetBindingsSheet() {
+
+}
+
+void TargetBindingsSheet::setShader(Shader *shader, Material *material, ShaderBinding *binding) {
+	this->shader = shader;
+	this->material = material;		
+	this->binding = binding;
+	
+	refreshTargets();
+}
+
+void TargetBindingsSheet::Update() {
+	if(bindingToRemove) {
+		binding->removeRenderTargetBinding(bindingToRemove);
+		bindingToRemove = NULL;
+		refreshTargets();
+	}
+}
+
+void TargetBindingsSheet::refreshTargets() {
+	for(int i=0; i < props.size(); i++) {
+		contents->removeChild(props[i]);
+		props[i]->removeAllHandlersForListener(this);
+		delete props[i];
+	}
+	props.clear();
+	propHeight = 0;
+
+	if(!material) {
+		return;
+	}
+	
+	for(int i=0; i < binding->getNumRenderTargetBindings(); i++) {
+		RenderTargetBinding *targetBinding = binding->getRenderTargetBinding(i);
+		TargetBindingProp *bindingProp = new TargetBindingProp(shader, material, binding, targetBinding);
+		bindingProp->addEventListener(this, Event::REMOVE_EVENT);	
+		addProp(bindingProp);
+		propHeight += 30;		
+		
+	}
+				
+	addButton->setPosition(15, propHeight);	
+	propHeight += 70;	
+
+	dispatchEvent(new Event(), Event::COMPLETE_EVENT);		
+	Resize(width, height);	
+}
+
+void TargetBindingsSheet::handleEvent(Event *event) {
+
+	if(event->getDispatcher() == addButton) {
+		RenderTargetBinding* newBinding = new RenderTargetBinding();
+		newBinding->mode = RenderTargetBinding::MODE_COLOR;
+		newBinding->texture = NULL;		
+		binding->addRenderTargetBinding(newBinding);				
+		refreshTargets();			
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+	}
+	
+	for(int i=0; i < props.size(); i++) {
+		if(event->getDispatcher() == props[i]) {
+			switch(event->getEventCode()) {						
+				case Event::REMOVE_EVENT:
+					bindingToRemove = ((TargetBindingProp*)props[i])->targetBinding;
+				break;
+				case Event::CHANGE_EVENT:
+					dispatchEvent(new Event(), Event::CHANGE_EVENT);
+				break;				
+			}
+		}
+	}
+	
+	
+	PropSheet::handleEvent(event);
+}
+
+
+RenderTargetsSheet::RenderTargetsSheet() : PropSheet("RENDER TARGETS", "renderTargets") {
+	propHeight = 70;
+	addButton = new UIButton("Add Render Target", 150);
+	addButton->addEventListener(this, UIEvent::CLICK_EVENT);
+	contents->addChild(addButton);
+	addButton->setPosition(15, 35);
+	
+	customUndoHandler = true;	
+	material = NULL;
+	binding = NULL;
+	
+	removeIndex = -1;	
+}
+
+RenderTargetsSheet::~RenderTargetsSheet() {
+
+}
+
+void RenderTargetsSheet::refreshTargets() {
+	for(int i=0; i < props.size(); i++) {
+		contents->removeChild(props[i]);
+		props[i]->removeAllHandlersForListener(this);
+		delete props[i];
+	}
+	props.clear();
+	propHeight = 0;
+
+	if(!material) {
+		return;
+	}
+	
+	for(int i=0; i < material->getNumShaderRenderTargets(); i++) {
+		ShaderRenderTarget *renderTarget  = material->getShaderRenderTarget(i);
+		RenderTargetProp *targetProp = new RenderTargetProp(renderTarget, material);		
+		targetProp->addEventListener(this, Event::CANCEL_EVENT);	
+		addProp(targetProp);
+		propHeight += 30;		
+	}
+	
+	addButton->setPosition(15, propHeight);	
+	propHeight += 70;	
+
+	dispatchEvent(new Event(), Event::COMPLETE_EVENT);		
+	Resize(width, height);	
+}
+
+void RenderTargetsSheet::Update() {
+	if(material != lastMaterial) {
+		lastMaterial = material;
+		refreshTargets();
+	}
+	
+	if(removeIndex != -1) {		
+		material->removeShaderRenderTarget(removeIndex);
+		removeIndex = -1;
+		refreshTargets();
+	}
+	
+}
+
+void RenderTargetsSheet::handleEvent(Event *event) {
+	if(!material)
+		return;
+
+	if(event->getDispatcher() == addButton) {
+		ShaderRenderTarget* newRenderTarget = new ShaderRenderTarget();
+		newRenderTarget->id = "render_target";
+		newRenderTarget->width = 1.0;
+		newRenderTarget->height = 1.0;
+		newRenderTarget->normalizedWidth = normTextureWidth;
+		newRenderTarget->normalizedHeight = normTextureHeight;		
+		newRenderTarget->sizeMode = ShaderRenderTarget::SIZE_MODE_NORMALIZED;		
+		material->addShaderRenderTarget(newRenderTarget);
+		refreshTargets();
+	}
+	
+	for(int i=0; i < props.size(); i++) {
+		if(event->getDispatcher() == props[i] && event->getEventType() == "") {
+			switch(event->getEventCode()) {						
+				case Event::CANCEL_EVENT:
+					removeIndex = i;
+				break;
+				case Event::CHANGE_EVENT:
+				break;				
+			}
+		}
+	}
+	
+	
+	PropSheet::handleEvent(event);
+}
+
+
 EntityPropSheet::EntityPropSheet() : PropSheet("CUSTOM PROPERTIES", "entityProps"){
 
 	propHeight = 75;
 	
 	addButton = new UIButton("Add Property", 150);
 	addButton->addEventListener(this, UIEvent::CLICK_EVENT);
-	addChild(addButton);
+	contents->addChild(addButton);
 	addButton->setPosition(15, 35);
 	
 	customUndoHandler = true;
@@ -1286,7 +1873,7 @@ void EntityPropSheet::refreshProps() {
 		delete props[i];
 	}
 	props.clear();
-	propHeight = 75;
+	propHeight = 0;
 	
 	for(int i=0; i < entity->entityProps.size(); i++) {			
 		EntityProp prop = entity->entityProps[i];
@@ -1294,15 +1881,15 @@ void EntityPropSheet::refreshProps() {
 		newProp->addEventListener(this, Event::CANCEL_EVENT);
 		newProp->addEventListener(this, Event::CHANGE_EVENT);		
 		addProp(newProp);
-		propHeight += 35;
+		propHeight += 30;
 	}
 	
 	
-	addButton->setPosition(15, propHeight-40);	
-	
+	addButton->setPosition(15, propHeight);	
+	propHeight += 70;	
 	
 	if(lastNumProps != entity->entityProps.size()) {
-		dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		dispatchEvent(new Event(), Event::COMPLETE_EVENT);
 	}
 	
 	lastNumProps = entity->entityProps.size();
@@ -1337,7 +1924,7 @@ void EntityPropSheet::Update() {
 	}
 }
 
-ShaderOptionsSheet::ShaderOptionsSheet(String title, String name) : PropSheet(title, name){
+ShaderOptionsSheet::ShaderOptionsSheet() : PropSheet("SHADER OPTIONS", "shader_options"){
 	shader = NULL;
 	propHeight = 40;
 }
@@ -1356,6 +1943,9 @@ void ShaderOptionsSheet::handleEvent(Event *event) {
 				} else if(props[i]->propType == "Color") {
 					(*(Color*)binding->getLocalParamByName(props[i]->label->getText())->data) = ((ColorProp*)props[i])->get();
 				
+				} else if(props[i]->propType == "Vector2") {
+					(*(Vector2*)binding->getLocalParamByName(props[i]->label->getText())->data) = ((Vector2Prop*)props[i])->get();
+				
 				}
 				dispatchEvent(new Event(), Event::CHANGE_EVENT);				
 				return;
@@ -1410,13 +2000,23 @@ void ShaderOptionsSheet::setOptionsFromParams(std::vector<ProgramParam> &params)
 						propHeight += 40;												
 					}
 					break;
-					
+					case ProgramParam::PARAM_VECTOR2:
+					{
+						String paramName = params[i].name;						
+						Vector2Prop *vec2Prop = new Vector2Prop(paramName);;
+						addProp(vec2Prop);
+						
+						Vector2 vec2val = (*(Vector2*)binding->getLocalParamByName(params[i].name)->data);
+						vec2Prop->set(vec2val);
+						propHeight += 30;
+					}
+					break;
 				}	
 			}
 		}	
 }
 
-void ShaderOptionsSheet::setShader(Shader *shader, Material *material) {
+void ShaderOptionsSheet::setShader(Shader *shader, Material *material, ShaderBinding *binding) {
 	clearShader();
 	this->shader = shader;
 	this->material = material;
@@ -1424,7 +2024,7 @@ void ShaderOptionsSheet::setShader(Shader *shader, Material *material) {
 	if(!shader || !material)
 		return;
 		
-	binding = material->getShaderBinding(0);
+	this->binding = binding;
 	
 	setOptionsFromParams(shader->expectedParams);
 	
@@ -1483,7 +2083,7 @@ void ShaderTexturesSheet::clearShader() {
 	propHeight = 30;
 }
 
-void ShaderTexturesSheet::setShader(Shader *shader, Material *material) {
+void ShaderTexturesSheet::setShader(Shader *shader, Material *material, ShaderBinding *binding) {
 	clearShader();
 	this->shader = shader;
 	this->material = material;
@@ -1491,7 +2091,7 @@ void ShaderTexturesSheet::setShader(Shader *shader, Material *material) {
 	if(!shader || !material)
 		return;
 		
-	binding = material->getShaderBinding(0);	
+	this->binding = binding;
 
 	for(int i=0; i < shader->expectedCubemaps.size(); i++) {
 		ComboProp *comboProp = new ComboProp(shader->expectedCubemaps[i]);

+ 4 - 1
Modules/Contents/UI/Include/PolyUIButton.h

@@ -35,7 +35,8 @@ namespace Polycode {
 	class _PolyExport UIButton : public UIElement {
 		public:
 			UIButton(String text, Number width, Number height = 23);
-			~UIButton();		
+			~UIButton();
+			void Resize(Number width, Number height);		
 			void handleEvent(Event *event);
 			
 			void Update();
@@ -44,6 +45,8 @@ namespace Polycode {
 		
 			CoreInput *coreInput;
 			
+			Number labelOffsetX;
+			Number labelOffsetY;
 			Number labelXPos;
 			Number labelYPos;
 			UIBox *buttonRect;

+ 2 - 0
Modules/Contents/UI/Include/PolyUITextInput.h

@@ -309,6 +309,8 @@ namespace Polycode {
 			 */
 			void insertText(String text);
 			
+			void setCaretPosition(int position);
+			
 			UIScrollContainer *getScrollContainer();
 			
 			bool useStrongHinting;

+ 17 - 2
Modules/Contents/UI/Source/PolyUIButton.cpp

@@ -42,8 +42,8 @@ UIButton::UIButton(String text, Number width, Number height) : UIElement() {
 	Number sb = conf->getNumericValue("Polycode", "uiButtonSkinB");
 	Number sl = conf->getNumericValue("Polycode", "uiButtonSkinL");
 
-	Number labelOffsetX = conf->getNumericValue("Polycode", "uiButtonLabelOffsetX");
-	Number labelOffsetY = conf->getNumericValue("Polycode", "uiButtonLabelOffsetY");
+	labelOffsetX = conf->getNumericValue("Polycode", "uiButtonLabelOffsetX");
+	labelOffsetY = conf->getNumericValue("Polycode", "uiButtonLabelOffsetY");
 		
 	buttonRect = new UIBox(conf->getStringValue("Polycode", "uiButtonSkin"),
 						   st,sr,sb,sl,
@@ -85,6 +85,21 @@ UIButton::UIButton(String text, Number width, Number height) : UIElement() {
 	
 }
 
+void UIButton::Resize(Number width, Number height) {
+	buttonRect->resizeBox(width, height);
+	buttonFocusedRect->resizeBox(width, height);
+	this->width = width;
+	this->height = height;	
+	matrixDirty = true;	
+	setHitbox(width,height);	
+	
+	labelXPos = floor((width-buttonLabel->getWidth())/2.0f) + labelOffsetX;
+	labelYPos = labelOffsetY;
+	buttonLabel->setPosition(labelXPos,labelYPos);
+	
+	UIElement::Resize(width, height);
+}
+
 void UIButton::Update() {
 	if(hasFocus) {
 		buttonFocusedRect->visible = true;

+ 1 - 0
Modules/Contents/UI/Source/PolyUIElement.cpp

@@ -42,4 +42,5 @@ UIElement::~UIElement() {
 void UIElement::Resize(Number width, Number height) {
 	setWidth(width);
 	setHeight(height);
+	dirtyMatrix(true);	
 }

+ 1 - 0
Modules/Contents/UI/Source/PolyUIHSizer.cpp

@@ -130,6 +130,7 @@ void UIHSizer::Resize(Number width, Number height) {
 	this->height = height;
 	matrixDirty = true;
 	updateSizer();
+	UIElement::Resize(width, height);	
 }
 
 Number UIHSizer::getMainWidth() {

+ 7 - 0
Modules/Contents/UI/Source/PolyUITextInput.cpp

@@ -607,6 +607,13 @@ void UITextInput::restructLines() {
 	
 }
 
+void UITextInput::setCaretPosition(int position) {
+	if(position >= 0 && position < lines[lineOffset].length()) {
+		caretPosition = position;
+		updateCaretPosition();		
+	}
+}
+
 void UITextInput::setText(String text, bool sendChangeEvent) {
 	if(!multiLine) {
 		lines[lineOffset] = text;

+ 3 - 0
Modules/Contents/UI/Source/PolyUIVSizer.cpp

@@ -26,6 +26,7 @@
 #include "PolyInputEvent.h"
 #include "PolyCoreServices.h"
 #include "PolyCore.h"
+#include "PolyUIEvent.h"
 
 using namespace Polycode;
 
@@ -132,6 +133,7 @@ void UIVSizer::Resize(Number width, Number height) {
 	this->height = height;
 	matrixDirty = true;
 	updateSizer();
+	UIElement::Resize(width, height);
 }
 
 Number UIVSizer::getMainHeight() {
@@ -141,6 +143,7 @@ Number UIVSizer::getMainHeight() {
 void UIVSizer::setMainHeight(Number height) {
 	mainHeight = height;
 	updateSizer();
+	dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT);
 }
 			
 void UIVSizer::addTopChild(UIElement *element) {