Quellcode durchsuchen

SceneMeshes now keep their own list of ShaderPasses, which are applied as options to materials but can provide additional render passes independent of the material, added support for global override materials in the new renderer, added wireframe support to renderer (non-ES2, will be ifdefed out in strict ES2 builds), readded wireframe overlay support as a separate shader pass, readded wireframe mode support in entity editor, added an lineSmooth option to GL renderer (non-ES2 as well)

Ivan Safrin vor 10 Jahren
Ursprung
Commit
a2134331c8

BIN
assets/default/default.pak


+ 9 - 0
assets/default/default/UnlitWireframe.frag

@@ -0,0 +1,9 @@
+#ifdef GLES2
+	precision mediump float;
+#endif
+
+uniform vec4 wireframeColor;
+
+void main() {
+	gl_FragColor = wireframeColor;
+}

+ 10 - 6
assets/default/default/default.mat

@@ -8,20 +8,24 @@
 		<shader type="glsl" name="UnlitUntextured" numPointLights="0" numSpotLights="0">		
 		<shader type="glsl" name="UnlitUntextured" numPointLights="0" numSpotLights="0">		
 			<vp source="default/UnlitUntextured.vert"/>
 			<vp source="default/UnlitUntextured.vert"/>
 			<fp source="default/UnlitUntextured.frag"/>
 			<fp source="default/UnlitUntextured.frag"/>
-		</shader>		
+		</shader>
+		<shader type="glsl" name="UnlitWireframe" numPointLights="0" numSpotLights="0">		
+			<vp source="default/UnlitUntextured.vert"/>
+			<fp source="default/UnlitWireframe.frag"/>
+		</shader>	
 	</shaders>	
 	</shaders>	
 	<materials>	
 	<materials>	
 		<material name="Unlit">
 		<material name="Unlit">
 			<shader name="Unlit">
 			<shader name="Unlit">
-				<textures>
-				</textures>				
 			</shader>
 			</shader>
 		</material>
 		</material>
 		<material name="UnlitUntextured">
 		<material name="UnlitUntextured">
 			<shader name="UnlitUntextured">
 			<shader name="UnlitUntextured">
-				<textures>
-				</textures>				
 			</shader>
 			</shader>
-		</material>		
+		</material>	
+		<material name="UnlitWireframe">
+			<shader name="UnlitWireframe" wireframe="true">
+			</shader>
+		</material>				
 	</materials>
 	</materials>
 </polycode>
 </polycode>

+ 3 - 1
include/polycode/core/PolyGPUDrawBuffer.h

@@ -38,6 +38,7 @@ namespace Polycode {
         bool alphaTest;
         bool alphaTest;
         bool backfaceCull;
         bool backfaceCull;
         bool depthOnly;
         bool depthOnly;
+        bool forceMaterial;
         unsigned int blendingMode;
         unsigned int blendingMode;
         Polycode::Rectangle scissorBox;
         Polycode::Rectangle scissorBox;
         bool enableScissor;
         bool enableScissor;
@@ -54,7 +55,7 @@ namespace Polycode {
         GPUDrawOptions options;
         GPUDrawOptions options;
         Matrix4 modelMatrix;
         Matrix4 modelMatrix;
         Material *material;
         Material *material;
-        ShaderBinding *shaderBinding;
+        std::vector<ShaderPass> shaderPasses;
         IndexDataArray *indexArray;
         IndexDataArray *indexArray;
     };
     };
     
     
@@ -71,6 +72,7 @@ namespace Polycode {
         bool clearDepthBuffer;
         bool clearDepthBuffer;
         bool clearColorBuffer;
         bool clearColorBuffer;
         Vector2 backingResolutionScale;
         Vector2 backingResolutionScale;
+        Material *globalMaterial;
         
         
         Polycode::Rectangle viewport;
         Polycode::Rectangle viewport;
         std::vector<GPUDrawCall> drawCalls;
         std::vector<GPUDrawCall> drawCalls;

+ 23 - 8
include/polycode/core/PolyMaterial.h

@@ -32,17 +32,33 @@ namespace Polycode {
 	class Shader;
 	class Shader;
 	class ShaderBinding;
 	class ShaderBinding;
 	class ShaderRenderTarget;
 	class ShaderRenderTarget;
+    
+    class _PolyExport ShaderPass {
+        public:
+            ShaderPass();
+            ShaderPass(Shader *shader);
+            Shader *shader;
+            bool wireframe;
+            unsigned short blendingMode;
+            ShaderBinding* shaderBinding;
+    };
 
 
 	class _PolyExport Material : public Resource {
 	class _PolyExport Material : public Resource {
 		public:
 		public:
 			explicit Material(const String& name);
 			explicit Material(const String& name);
 			virtual ~Material();
 			virtual ~Material();
-			
+
+			void addShaderPass(const ShaderPass &pass);
+			void addShaderPassAtIndex(const ShaderPass &pass, unsigned int shaderIndex);
+        
+            /* DEPRECATED! Use addShaderPass! */
 			void addShader(Shader *shader,ShaderBinding *shaderBinding);
 			void addShader(Shader *shader,ShaderBinding *shaderBinding);
+            /* DEPRECATED! Use addShaderPassAtIndex! */
 			void addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex);			
 			void addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex);			
-			unsigned int getNumShaders() const;
+			unsigned int getNumShaderPasses() const;
 			
 			
-			void removeShader(int shaderIndex);
+        
+			void removeShaderPass(int shaderIndex);
 			
 			
 			void addShaderRenderTarget(ShaderRenderTarget *newTarget);
 			void addShaderRenderTarget(ShaderRenderTarget *newTarget);
 			int getNumShaderRenderTargets();
 			int getNumShaderRenderTargets();
@@ -54,8 +70,10 @@ namespace Polycode {
 			void handleEvent(Event *event);
 			void handleEvent(Event *event);
 						
 						
 			const String& getName() const;
 			const String& getName() const;
-			Shader *getShader(unsigned int index) const;
+			ShaderPass getShaderPass(unsigned int index) const;
 			ShaderBinding *getShaderBinding(unsigned int index) const;
 			ShaderBinding *getShaderBinding(unsigned int index) const;
+			Shader *getShader(unsigned int index) const;
+        
 			void loadMaterial(const String& fileName);
 			void loadMaterial(const String& fileName);
 			
 			
 			void setName(const String &name);
 			void setName(const String &name);
@@ -67,14 +85,11 @@ namespace Polycode {
 			void *shaderModule;
 			void *shaderModule;
 			
 			
 			int blendingMode;
 			int blendingMode;
-        
-            bool wireframe;
 			bool screenMaterial;
 			bool screenMaterial;
 			
 			
 		protected:
 		protected:
 		
 		
-			std::vector<Shader*> materialShaders;
-			std::vector<ShaderBinding*> shaderBindings;
+			std::vector<ShaderPass> shaderPasses;
 			std::vector<ShaderRenderTarget*> renderTargets;
 			std::vector<ShaderRenderTarget*> renderTargets;
 					
 					
 			String name;
 			String name;

+ 4 - 0
include/polycode/core/PolyOpenGLGraphicsInterface.h

@@ -85,9 +85,13 @@ namespace Polycode {
         void enableBackfaceCulling(bool val);
         void enableBackfaceCulling(bool val);
         void setLineSize(Number lineSize);
         void setLineSize(Number lineSize);
         
         
+        void setWireframeMode(bool val);
+        
         void enableScissor(bool val);
         void enableScissor(bool val);
         void setScissorBox(const Polycode::Rectangle &box);
         void setScissorBox(const Polycode::Rectangle &box);
         
         
+        bool lineSmooth;
+        
 	protected:
 	protected:
 		
 		
         GLuint currentShaderID;
         GLuint currentShaderID;

+ 2 - 0
include/polycode/core/PolyRenderer.h

@@ -67,6 +67,8 @@ namespace Polycode {
             virtual void enableScissor(bool val) = 0;
             virtual void enableScissor(bool val) = 0;
             virtual void setScissorBox(const Polycode::Rectangle &box) = 0;
             virtual void setScissorBox(const Polycode::Rectangle &box) = 0;
         
         
+            virtual void setWireframeMode(bool val) = 0;
+        
             virtual void beginDrawCall() = 0;
             virtual void beginDrawCall() = 0;
             virtual void endDrawCall() = 0;
             virtual void endDrawCall() = 0;
     };
     };

+ 13 - 10
include/polycode/core/PolySceneMesh.h

@@ -74,11 +74,12 @@ namespace Polycode {
 			
 			
 			void Render(GPUDrawBuffer *buffer);
 			void Render(GPUDrawBuffer *buffer);
 			
 			
-            /**
-             * Returns the local material binding options for this mesh.
-             */
-			ShaderBinding *getLocalShaderOptions();
-			
+
+			ShaderPass getShaderPass(unsigned int index);
+            unsigned int getNumShaderPasses();
+            void addShaderPass(ShaderPass pass);
+            void removeShaderPass(int shaderIndex);
+        
 			/**
 			/**
 			* Returns the Mesh instance of the actual mesh.
 			* Returns the Mesh instance of the actual mesh.
 			*/
 			*/
@@ -193,11 +194,11 @@ namespace Polycode {
             /**
             /**
              * The Renderer has an ability to set an override material that is set for all rendered entities. If forceMaterial is set to true, this entity will always use its assigned material, even if an override material is set.
              * The Renderer has an ability to set an override material that is set for all rendered entities. If forceMaterial is set to true, this entity will always use its assigned material, even if an override material is set.
              */
              */
-            bool forceMaterial;
+            void setForceMaterial(bool forceMaterial);
+            bool getForceMaterial();
         
         
             virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
             virtual Entity *Clone(bool deepClone, bool ignoreEditorOnly) const;
-            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;
-        
+            virtual void applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const;        
             
             
             /**
             /**
              * Normally, translucent textures do not affect the depth buffer, but if this flag is set to true, this entity's alpha channel is written to the depth buffer at a preset threshold. This flag is set to false by default.
              * Normally, translucent textures do not affect the depth buffer, but if this flag is set to true, this entity's alpha channel is written to the depth buffer at a preset threshold. This flag is set to false by default.
@@ -208,7 +209,6 @@ namespace Polycode {
              * If this flag is set to false, backface culling is disabled when rendering this entity, rendering both sides of each face. Set to true by default.
              * If this flag is set to false, backface culling is disabled when rendering this entity, rendering both sides of each face. Set to true by default.
              */
              */
             bool backfaceCulled;
             bool backfaceCulled;
-        
             bool sendBoneMatricesToMaterial;
             bool sendBoneMatricesToMaterial;
 			
 			
 		protected:
 		protected:
@@ -217,9 +217,12 @@ namespace Polycode {
 			Mesh *mesh;
 			Mesh *mesh;
 			Material *material;
 			Material *material;
 			Skeleton *skeleton;
 			Skeleton *skeleton;
-			ShaderBinding *localShaderOptions;
+        
+            std::vector<ShaderPass> shaderPasses;
+        
             String fileName;
             String fileName;
             std::vector<Matrix4> materialBoneMatrices;
             std::vector<Matrix4> materialBoneMatrices;
+                    
         
         
             VertexDataArray skeletalVertexPositions;
             VertexDataArray skeletalVertexPositions;
             VertexDataArray skeletalVertexNormals;
             VertexDataArray skeletalVertexNormals;

+ 3 - 2
include/polycode/modules/ui/PolyUIElement.h

@@ -58,7 +58,7 @@ namespace Polycode {
 			void focusPreviousChild();
 			void focusPreviousChild();
 			bool isFocusable();
 			bool isFocusable();
 			void focusSelf();
 			void focusSelf();
-									
+        
 			virtual void onLoseFocus() {}
 			virtual void onLoseFocus() {}
 			virtual void onGainFocus() {}
 			virtual void onGainFocus() {}
 			
 			
@@ -100,6 +100,7 @@ namespace Polycode {
 			void setImageCoordinates(Number x, Number y, Number width, Number height, Number imageScale = 1.0);
 			void setImageCoordinates(Number x, Number y, Number width, Number height, Number imageScale = 1.0);
 			Number getImageWidth() const;
 			Number getImageWidth() const;
 			Number getImageHeight() const;
 			Number getImageHeight() const;
+            void setMaterial(Material *material);
         
         
 			Texture *getTexture();			
 			Texture *getTexture();			
 		protected:
 		protected:
@@ -108,7 +109,7 @@ namespace Polycode {
 			Number imageHeight;
 			Number imageHeight;
         
         
             Material *material;
             Material *material;
-            ShaderBinding *localShaderOptions;
+            std::vector<ShaderPass> shaderPasses;
 			
 			
 			Mesh *rectMesh;
 			Mesh *rectMesh;
 			Texture *texture;
 			Texture *texture;

+ 4 - 1
src/core/PolyCocoaCore.mm

@@ -129,7 +129,10 @@ CocoaCore::CocoaCore(PolycodeView *view, int _xRes, int _yRes, bool fullScreen,
 	initTime = mach_absolute_time();					
 	initTime = mach_absolute_time();					
 
 
     renderer = new Renderer();
     renderer = new Renderer();
-    renderer->setGraphicsInterface(this, new OpenGLGraphicsInterface());
+    
+    OpenGLGraphicsInterface *interface = new OpenGLGraphicsInterface();
+    interface->lineSmooth = true;
+    renderer->setGraphicsInterface(this, interface);
     services->setRenderer(renderer);
     services->setRenderer(renderer);
     setVideoMode(xRes, yRes, fullScreen, vSync, aaLevel, anisotropyLevel, retinaSupport);
     setVideoMode(xRes, yRes, fullScreen, vSync, aaLevel, anisotropyLevel, retinaSupport);
     
     

+ 1 - 0
src/core/PolyEntity.cpp

@@ -57,6 +57,7 @@ void Entity::initEntity() {
 	parentEntity = NULL;
 	parentEntity = NULL;
 	matrixDirty = true;
 	matrixDirty = true;
 	billboardMode = false;
 	billboardMode = false;
+    drawCall.options.forceMaterial = false;
 	drawCall.options.depthOnly = false;
 	drawCall.options.depthOnly = false;
 	drawCall.options.blendingMode = Entity::defaultBlendingMode;    
 	drawCall.options.blendingMode = Entity::defaultBlendingMode;    
 	depthWrite = true;
 	depthWrite = true;

+ 66 - 46
src/core/PolyMaterial.cpp

@@ -30,13 +30,31 @@
 
 
 using namespace Polycode;
 using namespace Polycode;
 
 
+ShaderPass::ShaderPass() :
+    shader(NULL),
+    wireframe(false),
+    shaderBinding(NULL),
+    blendingMode(Renderer::BLEND_MODE_NONE)
+{
+    
+}
+
+ShaderPass::ShaderPass(Shader *shader) :
+    shader(shader),
+    wireframe(false),
+    shaderBinding(NULL),
+    blendingMode(Renderer::BLEND_MODE_NONE)
+{
+    
+}
+
+
 Material::Material(const String& name) : Resource(Resource::RESOURCE_MATERIAL) {
 Material::Material(const String& name) : Resource(Resource::RESOURCE_MATERIAL) {
 	this->name = name;
 	this->name = name;
 	fp16RenderTargets = false;
 	fp16RenderTargets = false;
 	shaderModule = NULL;
 	shaderModule = NULL;
 	blendingMode = Renderer::BLEND_MODE_NORMAL;
 	blendingMode = Renderer::BLEND_MODE_NORMAL;
 	screenMaterial = false;
 	screenMaterial = false;
-    wireframe = false;
 }
 }
 
 
 Material::~Material() {
 Material::~Material() {
@@ -53,6 +71,8 @@ void Material::setName(const String &name) {
 }
 }
 
 
 void Material::clearShaders() {
 void Material::clearShaders() {
+    
+    // SMARTPTR_TODO: add here
 	// do not delete shaders here, they're shared
 	// do not delete shaders here, they're shared
 /*	
 /*	
 	for(int i=0; i < materialShaders.size(); i++)	{
 	for(int i=0; i < materialShaders.size(); i++)	{
@@ -60,15 +80,11 @@ void Material::clearShaders() {
 	}
 	}
 	*/
 	*/
 	
 	
-	for(int i=0; i < materialShaders.size(); i++)	{
-		materialShaders[i]->removeAllHandlersForListener(this);
+	for(int i=0; i < shaderPasses.size(); i++)	{
+		shaderPasses[i].shader->removeAllHandlersForListener(this);
+        delete shaderPasses[i].shaderBinding;
 	}	
 	}	
-	materialShaders.clear();
-
-	for(int i=0; i < shaderBindings.size(); i++)	{
-		delete shaderBindings[i];
-	}
-	shaderBindings.clear();
+	shaderPasses.clear();
 	
 	
 	for(int i=0; i < renderTargets.size(); i++)	{
 	for(int i=0; i < renderTargets.size(); i++)	{
 		delete renderTargets[i];
 		delete renderTargets[i];
@@ -158,64 +174,68 @@ void Material::handleEvent(Event *event) {
      */
      */
 }
 }
 
 
-void Material::removeShader(int shaderIndex) {
-	if(shaderIndex >= 0 && shaderIndex < materialShaders.size()) {
-		materialShaders.erase(materialShaders.begin() + shaderIndex);
-		shaderBindings.erase(shaderBindings.begin() + shaderIndex);		
+void Material::removeShaderPass(int shaderIndex) {
+	if(shaderIndex >= 0 && shaderIndex < shaderPasses.size()) {
+        delete shaderPasses[shaderIndex].shaderBinding;
+		shaderPasses.erase(shaderPasses.begin() + shaderIndex);
 	}
 	}
 }
 }
 
 
 void Material::addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex) {
 void Material::addShaderAtIndex(Shader *shader,ShaderBinding *shaderBinding, int shaderIndex) {
-        // RENDERER_TODO
+    ShaderPass newPass;
+    newPass.shader = shader;
+    newPass.shaderBinding = shaderBinding;
+	shaderPasses.insert(shaderPasses.begin()+shaderIndex, newPass);
+	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
+}
 
 
-	materialShaders.insert(materialShaders.begin()+shaderIndex, shader);
-	shaderBindings.insert(shaderBindings.begin()+shaderIndex, shaderBinding);
-	
-	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);	
-	
-    /*
-	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::addShaderPass(const ShaderPass &pass) {
+    shaderPasses.push_back(pass);
+    pass.shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
 }
 }
-			
-void Material::addShader(Shader *shader,ShaderBinding *shaderBinding) {
 
 
-	materialShaders.push_back(shader);
-	shaderBindings.push_back(shaderBinding);
+void Material::addShaderPassAtIndex(const ShaderPass &pass, unsigned int shaderIndex) {
+    shaderPasses.insert(shaderPasses.begin()+shaderIndex, pass);
+    pass.shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
+}
+
+
+void Material::addShader(Shader *shader,ShaderBinding *shaderBinding) {
+    ShaderPass newPass;
+    newPass.shader = shader;
+    newPass.shaderBinding = shaderBinding;
+	shaderPasses.push_back(newPass);
 	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
 	shader->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
-    /*
-	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);
-		}
-	}	
-     */
 }
 }
 
 
 
 
-unsigned int Material::getNumShaders() const {
-	return materialShaders.size();
+unsigned int Material::getNumShaderPasses() const {
+	return shaderPasses.size();
 }
 }
 
 
 const String& Material::getName() const {
 const String& Material::getName() const {
 	return name;
 	return name;
 }
 }
 
 
+ShaderPass Material::getShaderPass(unsigned int index) const {
+	if(index < shaderPasses.size()) {
+		return shaderPasses[index];
+    } else {
+        return ShaderPass();
+    }
+}
+
 Shader *Material::getShader(unsigned int index) const {
 Shader *Material::getShader(unsigned int index) const {
-	if(index < materialShaders.size()) { 
-		return materialShaders[index];
-	} else {
-		return NULL;
-	}
+    if(index < shaderPasses.size()) {
+        return shaderPasses[index].shader;
+    } else {
+        return NULL;
+    }
 }
 }
 
 
 ShaderBinding *Material::getShaderBinding(unsigned int index) const {
 ShaderBinding *Material::getShaderBinding(unsigned int index) const {
-	if(index < shaderBindings.size()) {
-		return shaderBindings[index]; 
+	if(index < shaderPasses.size()) {
+		return shaderPasses[index].shaderBinding;
 	} else {
 	} else {
 		return NULL;
 		return NULL;
 	}
 	}

+ 21 - 23
src/core/PolyMaterialManager.cpp

@@ -435,11 +435,8 @@ Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXml
 
 
 	String mname = nodeElement->Attribute("name");
 	String mname = nodeElement->Attribute("name");
 	TiXmlNode* pChild, *pChild2,*pChild3;
 	TiXmlNode* pChild, *pChild2,*pChild3;
-	Shader *materialShader;
-	ShaderBinding *newShaderBinding;
 	
 	
-	vector<Shader*> materialShaders;
-	vector<ShaderBinding*> newShaderBindings;
+	vector<ShaderPass> shaderPasses;
 	vector<ShaderRenderTarget*> renderTargets;
 	vector<ShaderRenderTarget*> renderTargets;
 
 
 	Material *newMaterial = new Material(mname);
 	Material *newMaterial = new Material(mname);
@@ -451,10 +448,6 @@ Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXml
 			newMaterial->screenMaterial = true;
 			newMaterial->screenMaterial = true;
 		}
 		}
 	}
 	}
-    
-	if(nodeElement->Attribute("wireframe")) {
-		newMaterial->wireframe = String(nodeElement->Attribute("wireframe")) == "true";
-	}
 	
 	
 	if(nodeElement->Attribute("blendingMode")) {
 	if(nodeElement->Attribute("blendingMode")) {
 		newMaterial->blendingMode = atoi(nodeElement->Attribute("blendingMode"));
 		newMaterial->blendingMode = atoi(nodeElement->Attribute("blendingMode"));
@@ -515,15 +508,23 @@ Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXml
 		if (!pChild3Element) continue; // Skip comment nodes
 		if (!pChild3Element) continue; // Skip comment nodes
 		
 		
 		if(strcmp(pChild3->Value(), "shader") == 0) {
 		if(strcmp(pChild3->Value(), "shader") == 0) {
-			materialShader = setShaderFromXMLNode(resourcePool, pChild3);
-			if(materialShader) {
-                newShaderBinding = new ShaderBinding();
-				materialShaders.push_back(materialShader);
-				newShaderBindings.push_back(newShaderBinding);
+            
+            ShaderPass shaderPass;
+            
+			shaderPass.shader = setShaderFromXMLNode(resourcePool, pChild3);
+            
+            TiXmlElement *nodeElement = pChild3->ToElement();
+            if(nodeElement->Attribute("wireframe")) {
+                shaderPass.wireframe = String(nodeElement->Attribute("wireframe")) == "true";
+            }
+            
+			if(shaderPass.shader) {
+                shaderPass.shaderBinding = new ShaderBinding();
+				shaderPasses.push_back(shaderPass);
 				for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
 				for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
 					TiXmlElement *pChildElement = pChild->ToElement();
 					TiXmlElement *pChildElement = pChild->ToElement();
 					if (!pChildElement) continue; // Skip comment nodes
 					if (!pChildElement) continue; // Skip comment nodes
-
+                    
 					if(strcmp(pChild->Value(), "params") == 0) {
 					if(strcmp(pChild->Value(), "params") == 0) {
 						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
 						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
 							TiXmlElement *pChild2Element = pChild2->ToElement();
 							TiXmlElement *pChild2Element = pChild2->ToElement();
@@ -534,8 +535,8 @@ Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXml
 
 
 
 
                                     String pvalue =  pChild2Element->Attribute("value");
                                     String pvalue =  pChild2Element->Attribute("value");
-                                    int type = materialShader->getExpectedParamType(pname);
-                                    LocalShaderParam *param = newShaderBinding->addParam(type, pname);
+                                    int type = shaderPass.shader->getExpectedParamType(pname);
+                                    LocalShaderParam *param = shaderPass.shaderBinding->addParam(type, pname);
                                     if(param) {
                                     if(param) {
                                         param->setParamValueFromString(type, pvalue);
                                         param->setParamValueFromString(type, pvalue);
                                     }
                                     }
@@ -569,7 +570,7 @@ Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXml
 									newBinding->mode = RenderTargetBinding::MODE_OUT;								
 									newBinding->mode = RenderTargetBinding::MODE_OUT;								
 								}
 								}
 																
 																
-								newShaderBinding->addRenderTargetBinding(newBinding);
+								shaderPass.shaderBinding->addRenderTargetBinding(newBinding);
 								
 								
 								for(int l=0; l < renderTargets.size(); l++) {
 								for(int l=0; l < renderTargets.size(); l++) {
 									if(renderTargets[l]->id == newBinding->id) {
 									if(renderTargets[l]->id == newBinding->id) {
@@ -596,7 +597,7 @@ Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXml
 									tname =  pChild2Element->Attribute("name");
 									tname =  pChild2Element->Attribute("name");
 								}
 								}
 								Texture *texture = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(pChild2Element->GetText());
 								Texture *texture = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(pChild2Element->GetText());
-                                newShaderBinding->setTextureForParam(tname, texture);
+                                shaderPass.shaderBinding->setTextureForParam(tname, texture);
 							}
 							}
 							
 							
 							if(strcmp(pChild2->Value(), "cubemap") == 0){
 							if(strcmp(pChild2->Value(), "cubemap") == 0){
@@ -616,11 +617,8 @@ Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, TiXml
 	}
 	}
 	
 	
 
 
-	for(int i=0; i< materialShaders.size(); i++) {
-		newMaterial->addShader(materialShaders[i],newShaderBindings[i]);
-	}
-	for(int i=0; i< renderTargets.size(); i++) {
-		newMaterial->addShaderRenderTarget(renderTargets[i]);
+	for(int i=0; i< shaderPasses.size(); i++) {
+		newMaterial->addShaderPass(shaderPasses[i]);
 	}
 	}
 	
 	
 	return newMaterial;
 	return newMaterial;

+ 1 - 0
src/core/PolyMesh.cpp

@@ -879,6 +879,7 @@ unsigned int Mesh::getIndexCount() {
     return indexArray.data.size();
     return indexArray.data.size();
 }
 }
 
 
+
 void Mesh::createTorus(Number radius, Number tubeRadius, int segmentsW, int segmentsH, Number tilingValue) {
 void Mesh::createTorus(Number radius, Number tubeRadius, int segmentsW, int segmentsH, Number tilingValue) {
 
 
     segmentsH++;
     segmentsH++;

+ 16 - 1
src/core/PolyOpenGLGraphicsInterface.cpp

@@ -28,7 +28,7 @@
 using namespace Polycode;
 using namespace Polycode;
 
 
 OpenGLGraphicsInterface::OpenGLGraphicsInterface() {
 OpenGLGraphicsInterface::OpenGLGraphicsInterface() {
-
+    lineSmooth = false;
 }
 }
 
 
 OpenGLGraphicsInterface::~OpenGLGraphicsInterface() {
 OpenGLGraphicsInterface::~OpenGLGraphicsInterface() {
@@ -155,6 +155,11 @@ void OpenGLGraphicsInterface::setBlendingMode(unsigned int blendingMode) {
 
 
 void OpenGLGraphicsInterface::beginDrawCall() {
 void OpenGLGraphicsInterface::beginDrawCall() {
     textureIndex = 0;
     textureIndex = 0;
+#ifndef STRICT_OPENGLES2
+    if(lineSmooth) {
+        glEnable(GL_LINE_SMOOTH);
+    }
+#endif
 }
 }
 
 
 void OpenGLGraphicsInterface::endDrawCall() {
 void OpenGLGraphicsInterface::endDrawCall() {
@@ -203,6 +208,16 @@ void OpenGLGraphicsInterface::setScissorBox(const Polycode::Rectangle &box) {
     
     
 }
 }
 
 
+void OpenGLGraphicsInterface::setWireframeMode(bool val) {
+#ifndef STRICT_OPENGLES2
+    if(val) {
+        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
+    } else {
+        glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
+    }
+#endif
+}
+
 GLenum OpenGLGraphicsInterface::getGLDrawMode(int polycodeMode) {
 GLenum OpenGLGraphicsInterface::getGLDrawMode(int polycodeMode) {
     switch(polycodeMode) {
     switch(polycodeMode) {
         case Mesh::POINT_MESH:
         case Mesh::POINT_MESH:

+ 46 - 28
src/core/PolyRenderer.cpp

@@ -98,27 +98,44 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
         
         
         modelMatrixParam->setMatrix4(buffer->drawCalls[i].modelMatrix);
         modelMatrixParam->setMatrix4(buffer->drawCalls[i].modelMatrix);
         
         
-        if(buffer->drawCalls[i].material) {
-            
+        Material *material = buffer->drawCalls[i].material;
+        if(buffer->globalMaterial && !buffer->drawCalls[i].options.forceMaterial) {
+            material = buffer->globalMaterial;
+        }
+        
+        if(material) {
             
             
-            if(buffer->drawCalls[i].options.blendingMode == Renderer::BLEND_MODE_MATERIAL) {
-                graphicsInterface->setBlendingMode(buffer->drawCalls[i].material->blendingMode);
+            if(buffer->drawCalls[i].options.blendingMode == Renderer::BLEND_MODE_MATERIAL || buffer->globalMaterial) {
+                graphicsInterface->setBlendingMode(material->blendingMode);
             } else {
             } else {
                 graphicsInterface->setBlendingMode(buffer->drawCalls[i].options.blendingMode);
                 graphicsInterface->setBlendingMode(buffer->drawCalls[i].options.blendingMode);
             }
             }
             
             
-            ShaderBinding *localShaderBinding = buffer->drawCalls[i].shaderBinding;
             
             
-            for(int s=0; s < buffer->drawCalls[i].material->getNumShaders(); s++) {
+            for(int s=0; s < buffer->drawCalls[i].shaderPasses.size(); s++) {
         
         
                 ++currentDebugFrameInfo.drawCallsProcessed;
                 ++currentDebugFrameInfo.drawCallsProcessed;
                 graphicsInterface->beginDrawCall();
                 graphicsInterface->beginDrawCall();
                 
                 
-                Shader *shader = buffer->drawCalls[i].material->getShader(s);
-                graphicsInterface->useShader(shader);
+                ShaderPass shaderPass;
+                if(s < material->getNumShaderPasses()) {
+                    shaderPass = material->getShaderPass(s);
+                } else {
+                    shaderPass = buffer->drawCalls[i].shaderPasses[s];
+                    graphicsInterface->setBlendingMode(shaderPass.blendingMode);
+                }
+                ShaderBinding *localShaderBinding = buffer->drawCalls[i].shaderPasses[s].shaderBinding;
+
+                if(!shaderPass.shader || !localShaderBinding) {
+                    continue;
+                }
                 
                 
-                ShaderBinding *materialShaderBinding = buffer->drawCalls[i].material->getShaderBinding(s);
+                graphicsInterface->useShader(shaderPass.shader);
 
 
+
+                graphicsInterface->setWireframeMode(shaderPass.wireframe);
+                
+                ShaderBinding *materialShaderBinding = material->getShaderBinding(s);
                 
                 
                 // set shader uniforms
                 // set shader uniforms
                 
                 
@@ -130,27 +147,28 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
         // TODO: can't cache the param here, need a better system (move to material binding?)
         // TODO: can't cache the param here, need a better system (move to material binding?)
                         
                         
 //                        if(!localParam->param) {
 //                        if(!localParam->param) {
-                            localParam->param = shader->getParamPointer(localParam->name);
+                            localParam->param = shaderPass.shader->getParamPointer(localParam->name);
   //                      }
   //                      }
                         if(localParam->param) {
                         if(localParam->param) {
-                            graphicsInterface->setParamInShader(shader, localParam->param, localParam);
+                            graphicsInterface->setParamInShader(shaderPass.shader, localParam->param, localParam);
                         }
                         }
                     }
                     }
                     
                     
                 }
                 }
    
    
-                for(int p=0; p < materialShaderBinding->getNumLocalParams(); p++) {
-                    
-                    LocalShaderParam *localParam = materialShaderBinding->getLocalParam(p);
-                    if(localParam) {
-                        if(!localParam->param) {
-                            localParam->param = shader->getParamPointer(localParam->name);
-                        }
-                        if(localParam->param) {
-                            graphicsInterface->setParamInShader(shader, localParam->param, localParam);
+                if(materialShaderBinding) {
+                    for(int p=0; p < materialShaderBinding->getNumLocalParams(); p++) {                        
+                        LocalShaderParam *localParam = materialShaderBinding->getLocalParam(p);
+                        if(localParam) {
+                            if(!localParam->param) {
+                                localParam->param = shaderPass.shader->getParamPointer(localParam->name);
+                            }
+                            if(localParam->param) {
+                                graphicsInterface->setParamInShader(shaderPass.shader, localParam->param, localParam);
+                            }
                         }
                         }
-                    }
 
 
+                    }
                 }
                 }
                 
                 
                 for(int p=0; p < localShaderBinding->getNumLocalParams(); p++) {
                 for(int p=0; p < localShaderBinding->getNumLocalParams(); p++) {
@@ -158,10 +176,10 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
                     LocalShaderParam *localParam = localShaderBinding->getLocalParam(p);
                     LocalShaderParam *localParam = localShaderBinding->getLocalParam(p);
                     if(localParam) {
                     if(localParam) {
                         if(!localParam->param) {
                         if(!localParam->param) {
-                            localParam->param = shader->getParamPointer(localParam->name);
+                            localParam->param = shaderPass.shader->getParamPointer(localParam->name);
                         }
                         }
                         if(localParam->param) {
                         if(localParam->param) {
-                            graphicsInterface->setParamInShader(shader, localParam->param, localParam);
+                            graphicsInterface->setParamInShader(shaderPass.shader, localParam->param, localParam);
                         }
                         }
                     }
                     }
                     
                     
@@ -175,12 +193,12 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
                         if(attributeBinding->enabled) {
                         if(attributeBinding->enabled) {
                             
                             
                             if(!attributeBinding->attribute) {
                             if(!attributeBinding->attribute) {
-                                attributeBinding->attribute = shader->getAttribPointer(attributeBinding->name);
+                                attributeBinding->attribute = shaderPass.shader->getAttribPointer(attributeBinding->name);
                             }
                             }
                             if(attributeBinding->attribute) {
                             if(attributeBinding->attribute) {
                                 
                                 
                                 if(attributeBinding->vertexData->data.size() / attributeBinding->vertexData->countPerVertex >= buffer->drawCalls[i].numVertices) {
                                 if(attributeBinding->vertexData->data.size() / attributeBinding->vertexData->countPerVertex >= buffer->drawCalls[i].numVertices) {
-                                    graphicsInterface->setAttributeInShader(shader, attributeBinding->attribute, attributeBinding);
+                                    graphicsInterface->setAttributeInShader(shaderPass.shader, attributeBinding->attribute, attributeBinding);
                                 }
                                 }
                             } else {
                             } else {
                                 attributeBinding->enabled = false;
                                 attributeBinding->enabled = false;
@@ -197,9 +215,9 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
                 }
                 }
                 
                 
                 
                 
-                for(int a=0; a < shader->expectedAttributes.size(); a++) {
-                    ProgramAttribute attribute = shader->expectedAttributes[a];
-                    graphicsInterface->disableAttribute(shader, attribute);
+                for(int a=0; a < shaderPass.shader->expectedAttributes.size(); a++) {
+                    ProgramAttribute attribute = shaderPass.shader->expectedAttributes[a];
+                    graphicsInterface->disableAttribute(shaderPass.shader, attribute);
                 }
                 }
                 
                 
                 graphicsInterface->endDrawCall();
                 graphicsInterface->endDrawCall();

+ 1 - 5
src/core/PolyScene.cpp

@@ -226,12 +226,8 @@ void Scene::Render(Camera *targetCamera, Texture *targetFramebuffer) {
     drawBuffer->clearColorBuffer = useClearColor;
     drawBuffer->clearColorBuffer = useClearColor;
     drawBuffer->clearDepthBuffer = useClearDepth;
     drawBuffer->clearDepthBuffer = useClearDepth;
     drawBuffer->targetFramebuffer = targetFramebuffer;
     drawBuffer->targetFramebuffer = targetFramebuffer;
-    
     drawBuffer->viewport = targetCamera->getViewport();
     drawBuffer->viewport = targetCamera->getViewport();
-///    drawBuffer->projectionMatrix = targetCamera->
-
-   // renderer->setOverrideMaterial(overrideMaterial);
-	
+    drawBuffer->globalMaterial = overrideMaterial;
 		
 		
 	//make these the closest
 	//make these the closest
 	
 	

+ 7 - 0
src/core/PolySceneEntityInstance.cpp

@@ -212,7 +212,10 @@ void SceneEntityInstance::applySceneMesh(ObjectEntry *entry, SceneMesh *sceneMes
                                             }
                                             }
                                              */
                                              */
                                         } else {
                                         } else {
+                                            // RENDERER_TODO
+                                            /*
                                             sceneMesh->getLocalShaderOptions()->setTextureForParam(nameEntry->stringVal, CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(textureEntry->stringVal));
                                             sceneMesh->getLocalShaderOptions()->setTextureForParam(nameEntry->stringVal, CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(textureEntry->stringVal));
+                                             */
                                         }
                                         }
                                     }
                                     }
                                 }
                                 }
@@ -230,10 +233,14 @@ void SceneEntityInstance::applySceneMesh(ObjectEntry *entry, SceneMesh *sceneMes
                                         Shader *materialShader = sceneMesh->getMaterial()->getShader(i);
                                         Shader *materialShader = sceneMesh->getMaterial()->getShader(i);
                                         if(materialShader) {
                                         if(materialShader) {
                                             int type = materialShader->getExpectedParamType(nameEntry->stringVal);
                                             int type = materialShader->getExpectedParamType(nameEntry->stringVal);
+                                            
+                                            // RENDERER_TODO
+                                            /*
                                             LocalShaderParam *param = sceneMesh->getLocalShaderOptions()->addParam(type, nameEntry->stringVal);
                                             LocalShaderParam *param = sceneMesh->getLocalShaderOptions()->addParam(type, nameEntry->stringVal);
                                             if(param) {
                                             if(param) {
                                                 param->setParamValueFromString(type, valueEntry->stringVal);
                                                 param->setParamValueFromString(type, valueEntry->stringVal);
                                             }
                                             }
+                                             */
                                         }
                                         }
                                     }
                                     }
                                     
                                     

+ 3 - 3
src/core/PolySceneImage.cpp

@@ -38,7 +38,7 @@ SceneImage* SceneImage::SceneImageWithTexture(Texture *texture) {
 SceneImage::SceneImage(const String& fileName) : ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 1, 1) {
 SceneImage::SceneImage(const String& fileName) : ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 1, 1) {
     
     
     // RENDERER_TODO
     // RENDERER_TODO
-    Texture *texture = localShaderOptions->loadTextureForParam("diffuse", fileName);
+    Texture *texture = getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", fileName);
 
 
 	imageWidth = texture->getWidth();
 	imageWidth = texture->getWidth();
 	imageHeight = texture->getHeight();
 	imageHeight = texture->getHeight();
@@ -52,7 +52,7 @@ SceneImage::SceneImage(Image *image) : ScenePrimitive(ScenePrimitive::TYPE_VPLAN
     // RENDERER_TODO
     // RENDERER_TODO
 	//loadTextureFromImage(image);
 	//loadTextureFromImage(image);
     Texture *texture = Services()->getMaterialManager()->createTextureFromImage(image);
     Texture *texture = Services()->getMaterialManager()->createTextureFromImage(image);
-    localShaderOptions->setTextureForParam("diffuse", texture);
+    getShaderPass(0).shaderBinding->setTextureForParam("diffuse", texture);
 
 
 	imageWidth = texture->getWidth();
 	imageWidth = texture->getWidth();
 	imageHeight = texture->getHeight();
 	imageHeight = texture->getHeight();
@@ -63,7 +63,7 @@ SceneImage::SceneImage(Image *image) : ScenePrimitive(ScenePrimitive::TYPE_VPLAN
 }
 }
 
 
 SceneImage::SceneImage(Texture *texture) : ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 1, 1)  {
 SceneImage::SceneImage(Texture *texture) : ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 1, 1)  {
-    localShaderOptions->setTextureForParam("diffuse", texture);
+    getShaderPass(0).shaderBinding->setTextureForParam("diffuse", texture);
 
 
 	imageWidth = texture->getWidth();
 	imageWidth = texture->getWidth();
 	imageHeight = texture->getHeight();
 	imageHeight = texture->getHeight();

+ 1 - 1
src/core/PolySceneLabel.cpp

@@ -121,7 +121,7 @@ void SceneLabel::updateFromLabel() {
 	
 	
     setLocalBoundingBox(label->getWidth()*labelScale / CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX(), label->getHeight()*labelScale/ CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX(), 0.001);
     setLocalBoundingBox(label->getWidth()*labelScale / CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX(), label->getHeight()*labelScale/ CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX(), 0.001);
     
     
-    localShaderOptions->setTextureForParam("diffuse", texture);
+    getShaderPass(0).shaderBinding->setTextureForParam("diffuse", texture);
     
     
 }
 }
 
 

+ 65 - 28
src/core/PolySceneMesh.cpp

@@ -43,7 +43,7 @@ SceneMesh *SceneMesh::SceneMeshWithType(int meshType) {
 	return new SceneMesh(meshType);
 	return new SceneMesh(meshType);
 }
 }
 
 
-SceneMesh::SceneMesh(const String& fileName) : Entity(), material(NULL), skeleton(NULL), localShaderOptions(NULL), mesh(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
+SceneMesh::SceneMesh(const String& fileName) : Entity(), material(NULL), skeleton(NULL), mesh(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
     loadFromFile(fileName);
     loadFromFile(fileName);
 	useVertexBuffer = false;
 	useVertexBuffer = false;
 	lineSmooth = false;
 	lineSmooth = false;
@@ -53,14 +53,13 @@ SceneMesh::SceneMesh(const String& fileName) : Entity(), material(NULL), skeleto
 	pointSize = 1.0;
 	pointSize = 1.0;
 	pointSmooth = false;
 	pointSmooth = false;
 	useGeometryHitDetection = false;
 	useGeometryHitDetection = false;
-    forceMaterial = false;
     backfaceCulled = true;
     backfaceCulled = true;
 	alphaTest = false;
 	alphaTest = false;
     sendBoneMatricesToMaterial = false;
     sendBoneMatricesToMaterial = false;
     setMaterialByName("UnlitUntextured");
     setMaterialByName("UnlitUntextured");
 }
 }
 
 
-SceneMesh::SceneMesh(Mesh *mesh) : Entity(), material(NULL), skeleton(NULL), localShaderOptions(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
+SceneMesh::SceneMesh(Mesh *mesh) : Entity(), material(NULL), skeleton(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
 	this->mesh = mesh;
 	this->mesh = mesh;
 	setLocalBoundingBox(mesh->calculateBBox());
 	setLocalBoundingBox(mesh->calculateBBox());
 	useVertexBuffer = false;
 	useVertexBuffer = false;
@@ -71,14 +70,13 @@ SceneMesh::SceneMesh(Mesh *mesh) : Entity(), material(NULL), skeleton(NULL), loc
 	pointSize = 1.0;
 	pointSize = 1.0;
 	pointSmooth = false;
 	pointSmooth = false;
 	useGeometryHitDetection = false;
 	useGeometryHitDetection = false;
-    forceMaterial = false;
     backfaceCulled = true;
     backfaceCulled = true;
 	alphaTest = false;
 	alphaTest = false;
     sendBoneMatricesToMaterial = false;
     sendBoneMatricesToMaterial = false;
     setMaterialByName("UnlitUntextured");
     setMaterialByName("UnlitUntextured");
 }
 }
 
 
-SceneMesh::SceneMesh(int meshType) : material(NULL), skeleton(NULL), localShaderOptions(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
+SceneMesh::SceneMesh(int meshType) : material(NULL), skeleton(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
 	mesh = new Mesh(meshType);
 	mesh = new Mesh(meshType);
 	setLocalBoundingBox(mesh->calculateBBox());
 	setLocalBoundingBox(mesh->calculateBBox());
 	useVertexBuffer = false;	
 	useVertexBuffer = false;	
@@ -87,7 +85,6 @@ SceneMesh::SceneMesh(int meshType) : material(NULL), skeleton(NULL), localShader
 	ownsSkeleton = true;	
 	ownsSkeleton = true;	
 	lineWidth = 1.0;
 	lineWidth = 1.0;
 	useGeometryHitDetection = false;
 	useGeometryHitDetection = false;
-    forceMaterial = false;
     backfaceCulled = true;
     backfaceCulled = true;
 	alphaTest = false;
 	alphaTest = false;
     sendBoneMatricesToMaterial = false;
     sendBoneMatricesToMaterial = false;
@@ -107,10 +104,12 @@ void SceneMesh::setMesh(Mesh *mesh) {
 }
 }
 
 
 void SceneMesh::rebuildAttributes() {
 void SceneMesh::rebuildAttributes() {
-    if(localShaderOptions) {
-        localShaderOptions->getAttributeBindingByName("texCoord")->vertexData = &mesh->vertexTexCoordArray;
-        localShaderOptions->getAttributeBindingByName("position")->vertexData = &mesh->vertexPositionArray;
-        localShaderOptions->getAttributeBindingByName("normal")->vertexData = &mesh->vertexNormalArray;
+    for(int i=0; i < shaderPasses.size(); i++) {
+        if(shaderPasses[i].shaderBinding) {
+            shaderPasses[i].shaderBinding->getAttributeBindingByName("texCoord")->vertexData = &mesh->vertexTexCoordArray;
+            shaderPasses[i].shaderBinding->getAttributeBindingByName("position")->vertexData = &mesh->vertexPositionArray;
+            shaderPasses[i].shaderBinding->getAttributeBindingByName("normal")->vertexData = &mesh->vertexNormalArray;
+        }
     }
     }
 }
 }
 
 
@@ -118,8 +117,11 @@ SceneMesh::~SceneMesh() {
 	if(ownsSkeleton)
 	if(ownsSkeleton)
 		delete skeleton;
 		delete skeleton;
 	if(ownsMesh)
 	if(ownsMesh)
-		delete mesh;	
-	delete localShaderOptions;
+		delete mesh;
+    
+    for(int i=0; i < shaderPasses.size(); i++)  {
+        delete shaderPasses[i].shaderBinding;
+    }
 }
 }
 
 
 Entity *SceneMesh::Clone(bool deepClone, bool ignoreEditorOnly) const {
 Entity *SceneMesh::Clone(bool deepClone, bool ignoreEditorOnly) const {
@@ -128,6 +130,14 @@ Entity *SceneMesh::Clone(bool deepClone, bool ignoreEditorOnly) const {
     return newEntity;
     return newEntity;
 }
 }
 
 
+void SceneMesh::setForceMaterial(bool forceMaterial) {
+    drawCall.options.forceMaterial = forceMaterial;
+}
+
+bool SceneMesh::getForceMaterial() {
+    return drawCall.options.forceMaterial;
+}
+
 void SceneMesh::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
 void SceneMesh::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly) const {
     Entity::applyClone(clone, deepClone, ignoreEditorOnly);
     Entity::applyClone(clone, deepClone, ignoreEditorOnly);
     SceneMesh *_clone = (SceneMesh*) clone;
     SceneMesh *_clone = (SceneMesh*) clone;
@@ -141,7 +151,6 @@ void SceneMesh::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly)
 	_clone->backfaceCulled = backfaceCulled;
 	_clone->backfaceCulled = backfaceCulled;
     _clone->ownsSkeleton = ownsSkeleton;
     _clone->ownsSkeleton = ownsSkeleton;
     _clone->useGeometryHitDetection = useGeometryHitDetection;
     _clone->useGeometryHitDetection = useGeometryHitDetection;
-    _clone->forceMaterial = forceMaterial;
     _clone->setFilename(fileName);
     _clone->setFilename(fileName);
     
     
     Mesh *newMesh = mesh->Copy();
     Mesh *newMesh = mesh->Copy();
@@ -149,7 +158,10 @@ void SceneMesh::applyClone(Entity *clone, bool deepClone, bool ignoreEditorOnly)
     
     
     _clone->setMaterial(material);
     _clone->setMaterial(material);
     if(material) {
     if(material) {
-        localShaderOptions->copyTo(_clone->getLocalShaderOptions());
+        
+        for(int i=0; i < shaderPasses.size(); i++) {
+            shaderPasses[i].shaderBinding->copyTo(_clone->getShaderPass(i).shaderBinding);
+        }
     }
     }
 }
 }
 
 
@@ -175,10 +187,11 @@ Mesh *SceneMesh::getMesh() {
 }
 }
 
 
 void SceneMesh::clearMaterial() {
 void SceneMesh::clearMaterial() {
-	if(localShaderOptions)
-		delete localShaderOptions;
-	localShaderOptions = NULL;
-	this->material = NULL;
+    for(int i=0; i < shaderPasses.size(); i++)  {
+        delete shaderPasses[i].shaderBinding;
+    }
+    shaderPasses.clear();
+    this->material = NULL;
 }
 }
 
 
 void SceneMesh::setMaterial(Material *material) {
 void SceneMesh::setMaterial(Material *material) {
@@ -189,18 +202,23 @@ void SceneMesh::setMaterial(Material *material) {
 	if(!material)
 	if(!material)
 		return;
 		return;
 		
 		
-	if(material->getNumShaders() == 0)
+	if(material->getNumShaderPasses() == 0)
 			return;
 			return;
 		
 		
 	this->material = material;
 	this->material = material;
-    localShaderOptions = new ShaderBinding();
     
     
-    localShaderOptions->addParamPointer(ProgramParam::PARAM_COLOR, "entityColor", &color);
+    for(int i=0; i < material->getNumShaderPasses(); i++)  {
+        ShaderPass shaderPass = material->getShaderPass(i);
+        shaderPass.shaderBinding = new ShaderBinding();
+        
+        shaderPass.shaderBinding->addParamPointer(ProgramParam::PARAM_COLOR, "entityColor", &color);
+        shaderPass.shaderBinding->addAttributeBinding("texCoord", &mesh->vertexTexCoordArray);
+        shaderPass.shaderBinding->addAttributeBinding("position", &mesh->vertexPositionArray);
+        shaderPass.shaderBinding->addAttributeBinding("normal", &mesh->vertexNormalArray);
+        
+        shaderPasses.push_back(shaderPass);
+    }
     
     
-    localShaderOptions->addAttributeBinding("texCoord", &mesh->vertexTexCoordArray);
-    localShaderOptions->addAttributeBinding("position", &mesh->vertexPositionArray);
-    localShaderOptions->addAttributeBinding("normal", &mesh->vertexNormalArray);
-	
 }
 }
 
 
 void SceneMesh::setMaterialByName(const String& materialName, ResourcePool *resourcePool) {
 void SceneMesh::setMaterialByName(const String& materialName, ResourcePool *resourcePool) {
@@ -214,8 +232,20 @@ void SceneMesh::setMaterialByName(const String& materialName, ResourcePool *reso
     setMaterial(material);
     setMaterial(material);
 }
 }
 
 
-ShaderBinding *SceneMesh::getLocalShaderOptions() {
-	return localShaderOptions;
+ShaderPass SceneMesh::getShaderPass(unsigned int index) {
+    if(index >= shaderPasses.size()) {
+        printf("WARNING: ACCESSING NON EXISTING SHADER PASS!\n");
+        return ShaderPass();
+    }
+    return shaderPasses[index];
+}
+
+unsigned int SceneMesh::getNumShaderPasses() {
+    return shaderPasses.size();
+}
+
+void SceneMesh::addShaderPass(ShaderPass pass) {
+    shaderPasses.push_back(pass);
 }
 }
 
 
 Skeleton *SceneMesh::loadSkeleton(const String& fileName) {
 Skeleton *SceneMesh::loadSkeleton(const String& fileName) {
@@ -344,6 +374,13 @@ bool SceneMesh::customHitDetection(const Ray &ray) {
 }
 }
 
 
 
 
+void SceneMesh::removeShaderPass(int shaderIndex) {
+    if(shaderIndex >= 0 && shaderIndex < shaderPasses.size()) {
+        delete shaderPasses[shaderIndex].shaderBinding;
+        shaderPasses.erase(shaderPasses.begin() + shaderIndex);
+    }
+}
+
 void SceneMesh::Render(GPUDrawBuffer *buffer) {
 void SceneMesh::Render(GPUDrawBuffer *buffer) {
     
     
     drawCall.options.alphaTest = alphaTest;
     drawCall.options.alphaTest = alphaTest;
@@ -366,7 +403,7 @@ void SceneMesh::Render(GPUDrawBuffer *buffer) {
     
     
     
     
     drawCall.material = material;
     drawCall.material = material;
-    drawCall.shaderBinding = localShaderOptions;
+    drawCall.shaderPasses = shaderPasses;
     
     
     buffer->drawCalls.push_back(drawCall);
     buffer->drawCalls.push_back(drawCall);
     
     

+ 2 - 2
src/core/PolySceneSprite.cpp

@@ -131,7 +131,7 @@ void SceneSprite::setSpriteSet(SpriteSet *spriteSet) {
     this->spriteSet = spriteSet;
     this->spriteSet = spriteSet;
     spriteSet->addEventListener(this, Event::CHANGE_EVENT);
     spriteSet->addEventListener(this, Event::CHANGE_EVENT);
     
     
-    localShaderOptions->setTextureForParam("diffuse", spriteSet->getTexture());
+    getShaderPass(0).shaderBinding->setTextureForParam("diffuse", spriteSet->getTexture());
     currentSprite = NULL;
     currentSprite = NULL;
     currentSpriteState = NULL;
     currentSpriteState = NULL;
 }
 }
@@ -218,7 +218,7 @@ void SceneSprite::Update() {
     setLocalBoundingBox(bBox.x / currentSpriteState->getPixelsPerUnit(), bBox.y / currentSpriteState->getPixelsPerUnit(), 0.001);
     setLocalBoundingBox(bBox.x / currentSpriteState->getPixelsPerUnit(), bBox.y / currentSpriteState->getPixelsPerUnit(), 0.001);
     
     
     spriteBoundingBox = currentSpriteState->getLargestFrameBoundingBox();    
     spriteBoundingBox = currentSpriteState->getLargestFrameBoundingBox();    
-    localShaderOptions->setTextureForParam("diffuse", spriteSet->getTexture());
+    getShaderPass(0).shaderBinding->setTextureForParam("diffuse", spriteSet->getTexture());
     
     
     if(paused) {
     if(paused) {
         return;
         return;

+ 11 - 1
src/ide/EditorGrid.cpp

@@ -102,6 +102,9 @@ EditorGrid::EditorGrid() : Entity() {
     Mesh *gridMesh = new Mesh(Mesh::LINE_MESH);
     Mesh *gridMesh = new Mesh(Mesh::LINE_MESH);
     
     
     grid = new SceneMesh(gridMesh);
     grid = new SceneMesh(gridMesh);
+    grid->setForceMaterial(true);
+    grid->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    
     grid->setColor(0.3, 0.3, 0.3, 1.0);
     grid->setColor(0.3, 0.3, 0.3, 1.0);
     grid->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX());
     grid->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX());
     addChild(grid);
     addChild(grid);
@@ -110,15 +113,22 @@ EditorGrid::EditorGrid() : Entity() {
     addChild(yLine);
     addChild(yLine);
     yLine->setColor(0.0, 0.8, 0.0, 1.0);
     yLine->setColor(0.0, 0.8, 0.0, 1.0);
     yLine->visible = false;
     yLine->visible = false;
+    yLine->setForceMaterial(true);
     
     
     xLine = new SceneLine(Vector3(), Vector3());
     xLine = new SceneLine(Vector3(), Vector3());
     addChild(xLine);
     addChild(xLine);
     xLine->setColor(0.8, 0.0, 0.0, 1.0);
     xLine->setColor(0.8, 0.0, 0.0, 1.0);
+    xLine->setForceMaterial(true);
     
     
     zLine = new SceneLine(Vector3(), Vector3());
     zLine = new SceneLine(Vector3(), Vector3());
     addChild(zLine);
     addChild(zLine);
     zLine->setColor(0.0, 0.0, 0.8, 1.0);
     zLine->setColor(0.0, 0.0, 0.8, 1.0);
-
+    zLine->setForceMaterial(true);
+    
+    xLine->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    yLine->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    zLine->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    
     gridSize = 1.0;
     gridSize = 1.0;
     gridLen = 16;
     gridLen = 16;
     
     

+ 4 - 5
src/ide/EntityEditorPropertyView.cpp

@@ -133,15 +133,14 @@ void EntityEditorPropertyView::updateShaderOptions() {
     shaderOptionsSheet->enabled = false;
     shaderOptionsSheet->enabled = false;
     
     
     if(sceneMesh) {
     if(sceneMesh) {
-        if(sceneMesh->getMaterial() && sceneMesh->getLocalShaderOptions()) {
+        if(sceneMesh->getMaterial() && sceneMesh->getNumShaderPasses() > 0) {
             
             
             // can't edit the textures manually on a scene label or sprite
             // can't edit the textures manually on a scene label or sprite
             if(!sceneLabel && !sceneSprite) {
             if(!sceneLabel && !sceneSprite) {
-            shaderTexturesSheet->setShader(sceneMesh->getMaterial()->getShader(0), sceneMesh->getMaterial(), sceneMesh->getLocalShaderOptions());
+            shaderTexturesSheet->setShader(sceneMesh->getMaterial()->getShader(0), sceneMesh->getMaterial(), sceneMesh->getShaderPass(0).shaderBinding);
                 shaderTexturesSheet->enabled = true;
                 shaderTexturesSheet->enabled = true;
-            }
-            
-            shaderOptionsSheet->setShader(sceneMesh->getMaterial()->getShader(0), sceneMesh->getMaterial(), sceneMesh->getLocalShaderOptions());
+            }            
+            shaderOptionsSheet->setShader(sceneMesh->getMaterial()->getShader(0), sceneMesh->getMaterial(), sceneMesh->getShaderPass(0).shaderBinding);
         }
         }
     }
     }
 }
 }

+ 49 - 17
src/ide/PolycodeEntityEditor.cpp

@@ -98,19 +98,22 @@ CurveDisplay::CurveDisplay(Scene *parentScene, SceneCurve *curve) : DummyTargetE
     controlPointLines = new SceneMesh(Mesh::LINE_MESH);
     controlPointLines = new SceneMesh(Mesh::LINE_MESH);
     controlPointLines->setColor(1.0, 1.0, 0.4, 1.0);
     controlPointLines->setColor(1.0, 1.0, 0.4, 1.0);
     addChild(controlPointLines);
     addChild(controlPointLines);
-    
+    controlPointLines->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    controlPointLines->setForceMaterial(true);
    
    
     mainPoints = new SceneMesh(Mesh::POINT_MESH);
     mainPoints = new SceneMesh(Mesh::POINT_MESH);
     mainPoints->setColor(0.0, 0.5, 1.0, 1.0);
     mainPoints->setColor(0.0, 0.5, 1.0, 1.0);
     addChild(mainPoints);
     addChild(mainPoints);
     mainPoints->pointSize = 10.0;
     mainPoints->pointSize = 10.0;
     mainPoints->pointSmooth = true;
     mainPoints->pointSmooth = true;
-
+    mainPoints->setForceMaterial(true);
+    
     controlPoints = new SceneMesh(Mesh::POINT_MESH);
     controlPoints = new SceneMesh(Mesh::POINT_MESH);
     controlPoints->setColor(1.0, 0.7, 0.0, 1.0);
     controlPoints->setColor(1.0, 0.7, 0.0, 1.0);
     addChild(controlPoints);
     addChild(controlPoints);
     controlPoints->pointSize = 8.0;
     controlPoints->pointSize = 8.0;
     controlPoints->pointSmooth = true;
     controlPoints->pointSmooth = true;
+    controlPoints->setForceMaterial(true);
     
     
     renderControlPoints = false;
     renderControlPoints = false;
     
     
@@ -284,12 +287,16 @@ LightDisplay::LightDisplay(SceneLight *light) : Entity() {
     addChild(spotSpot);
     addChild(spotSpot);
     spotSpot->setColor(1.0, 0.8, 0.0, 1.0);
     spotSpot->setColor(1.0, 0.8, 0.0, 1.0);
     spotSpot->enabled = false;
     spotSpot->enabled = false;
+    spotSpot->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    spotSpot->setForceMaterial(true);
     
     
     fovSceneMesh = new SceneMesh(Mesh::LINE_MESH);
     fovSceneMesh = new SceneMesh(Mesh::LINE_MESH);
     fovSceneMesh->setColor(1.0, 0.8, 0.0, 1.0);
     fovSceneMesh->setColor(1.0, 0.8, 0.0, 1.0);
     fovMesh = fovSceneMesh->getMesh();
     fovMesh = fovSceneMesh->getMesh();
     fovMesh->indexedMesh = true;
     fovMesh->indexedMesh = true;
     addChild(fovSceneMesh);
     addChild(fovSceneMesh);
+    fovSceneMesh->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    fovSceneMesh->setForceMaterial(true);
     
     
     fovMesh->addVertex(0.0, 0.0, 0.0);
     fovMesh->addVertex(0.0, 0.0, 0.0);
     
     
@@ -342,9 +349,11 @@ CameraDisplay::CameraDisplay(Camera *camera) : Entity() {
     editorOnly = true;
     editorOnly = true;
     
     
     fovSceneMesh = new SceneMesh(Mesh::LINE_MESH);
     fovSceneMesh = new SceneMesh(Mesh::LINE_MESH);
+    fovSceneMesh->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     fovSceneMesh->setColor(1.0, 0.0, 1.0, 1.0);
     fovSceneMesh->setColor(1.0, 0.0, 1.0, 1.0);
     fovMesh = fovSceneMesh->getMesh();
     fovMesh = fovSceneMesh->getMesh();
     fovMesh->indexedMesh = true;
     fovMesh->indexedMesh = true;
+    fovSceneMesh->setForceMaterial(true);
     
     
     fovMesh->addVertex(0.0, 0.0, 0.0);
     fovMesh->addVertex(0.0, 0.0, 0.0);
     
     
@@ -714,7 +723,7 @@ EntityEditorMainView::EntityEditorMainView(PolycodeEditor *editor) {
     bBoxVis = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 1.0, 1.0, 1.0);
     bBoxVis = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 1.0, 1.0, 1.0);
     bBoxVis->color = Color(0.3, 0.5, 1.0, 0.5);
     bBoxVis->color = Color(0.3, 0.5, 1.0, 0.5);
     bBoxVis->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     bBoxVis->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
-    mainScene->addChild(bBoxVis);
+    //mainScene->addChild(bBoxVis);
     
     
     editorMode = EDITOR_MODE_3D;
     editorMode = EDITOR_MODE_3D;
     
     
@@ -1001,13 +1010,11 @@ void EntityEditorMainView::createIcon(Entity *entity, String iconFile) {
     iconPrimitive->setMaterialByName("Unlit");
     iconPrimitive->setMaterialByName("Unlit");
     iconPrimitive->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     iconPrimitive->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("entityEditor/"+iconFile);
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("entityEditor/"+iconFile);
-	if(iconPrimitive->getLocalShaderOptions()) {
-        iconPrimitive->getLocalShaderOptions()->setTextureForParam("diffuse", tex);
-	}
+    iconPrimitive->getShaderPass(0).shaderBinding->setTextureForParam("diffuse", tex);
     
     
     addChild(iconPrimitive);
     addChild(iconPrimitive);
     iconPrimitive->setUserData((void*)entity);
     iconPrimitive->setUserData((void*)entity);
-    iconPrimitive->forceMaterial = true;
+    iconPrimitive->setForceMaterial(true);
     iconPrimitive->processInputEvents = true;
     iconPrimitive->processInputEvents = true;
     iconPrimitive->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
     iconPrimitive->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
     iconPrimitive->setUserData(entity);
     iconPrimitive->setUserData(entity);
@@ -1083,6 +1090,8 @@ void EntityEditorMainView::setEditorProps(Entity *entity) {
     
     
     SceneCurve *sceneCurve = dynamic_cast<SceneCurve*>(entity);
     SceneCurve *sceneCurve = dynamic_cast<SceneCurve*>(entity);
     if(sceneCurve) {
     if(sceneCurve) {
+        sceneCurve->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+        sceneCurve->setForceMaterial(true);
         CurveDisplay *curveVis = new CurveDisplay(mainScene, sceneCurve);
         CurveDisplay *curveVis = new CurveDisplay(mainScene, sceneCurve);
         curveVis->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
         curveVis->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
         createIcon(entity, "curve_icon.png");
         createIcon(entity, "curve_icon.png");
@@ -1552,7 +1561,14 @@ void EntityEditorMainView::handleEvent(Event *event) {
                 mainScene->setOverrideMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Default"));
                 mainScene->setOverrideMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Default"));
             break;
             break;
             case 2:
             case 2:
-                mainScene->setOverrideMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitWireframe"));
+            {
+                Material *wireframeMaterial = (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitWireframe");
+                
+                if(!wireframeMaterial->getShaderPass(0).shaderBinding->getLocalParamByName("wireframeColor")) {
+                    wireframeMaterial->getShaderPass(0).shaderBinding->addParam(ProgramParam::PARAM_COLOR, "wireframeColor")->setColor(Color(1.0, 1.0, 1.0, 1.0));
+                }
+                mainScene->setOverrideMaterial(wireframeMaterial);
+            }
             break;
             break;
         }
         }
     } else if(event->getDispatcher() == moveUpButton) {
     } else if(event->getDispatcher() == moveUpButton) {
@@ -1736,8 +1752,7 @@ Scene *EntityEditorMainView::getMainScene() {
 void EntityEditorMainView::doEntityDeselect(Entity *targetEntity) {
 void EntityEditorMainView::doEntityDeselect(Entity *targetEntity) {
     SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(targetEntity);
     SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(targetEntity);
     if(sceneMesh) {
     if(sceneMesh) {
-        // RENDERER_TODO
-        //sceneMesh->overlayWireframe = false;
+        setOverlayWireframeRecursive(sceneMesh, false);
     }
     }
     
     
     if(targetEntity == dummyEntity) {
     if(targetEntity == dummyEntity) {
@@ -1764,8 +1779,24 @@ void EntityEditorMainView::doEntityDeselect(Entity *targetEntity) {
 void EntityEditorMainView::setOverlayWireframeRecursive(Entity *targetEntity, bool val) {
 void EntityEditorMainView::setOverlayWireframeRecursive(Entity *targetEntity, bool val) {
     SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(targetEntity);
     SceneMesh *sceneMesh = dynamic_cast<SceneMesh*>(targetEntity);
     if(sceneMesh) {
     if(sceneMesh) {
-        // RENDERER_TODO
-            //sceneMesh->overlayWireframe = val;
+        Material *material = sceneMesh->getMaterial();
+        if(material) {
+            if(val) {
+                ShaderPass wireframePass;
+                wireframePass.shader = (Shader*)Services()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_SHADER, "UnlitWireframe");
+                wireframePass.wireframe = true;
+                wireframePass.shaderBinding = new ShaderBinding();
+                wireframePass.blendingMode = Renderer::BLEND_MODE_NORMAL;
+                wireframePass.shaderBinding->addAttributeBinding("position", &sceneMesh->getMesh()->vertexPositionArray);
+                wireframePass.shaderBinding->addParam(ProgramParam::PARAM_COLOR, "wireframeColor")->setColor(Color(0.5, 0.6, 1.0, 0.75));
+
+                
+                sceneMesh->addShaderPass(wireframePass);
+            } else {
+                sceneMesh->removeShaderPass(sceneMesh->getNumShaderPasses()-1);
+            }
+        }
+        
     }
     }
     for(int i=0; i < targetEntity->getNumChildren(); i++) {
     for(int i=0; i < targetEntity->getNumChildren(); i++) {
         setOverlayWireframeRecursive(targetEntity->getChildAtIndex(i), val);
         setOverlayWireframeRecursive(targetEntity->getChildAtIndex(i), val);
@@ -1777,8 +1808,7 @@ void EntityEditorMainView::doEntitySelect(Entity *targetEntity) {
     SceneParticleEmitter *emitter = dynamic_cast<SceneParticleEmitter*>(targetEntity);
     SceneParticleEmitter *emitter = dynamic_cast<SceneParticleEmitter*>(targetEntity);
     
     
     if(sceneMesh && ! emitter) {
     if(sceneMesh && ! emitter) {
-                // RENDERER_TODO
-//        sceneMesh->overlayWireframe = true;
+        setOverlayWireframeRecursive(sceneMesh, true);
     }
     }
     
     
     if(targetEntity == dummyEntity) {
     if(targetEntity == dummyEntity) {
@@ -2368,7 +2398,9 @@ void PolycodeEntityEditor::saveEntityToObjectEntry(Entity *entity, ObjectEntry *
         if(sceneMesh->getMaterial()) {
         if(sceneMesh->getMaterial()) {
             meshEntry->addChild("material", sceneMesh->getMaterial()->getResourceName());
             meshEntry->addChild("material", sceneMesh->getMaterial()->getResourceName());
             ObjectEntry *shaderOptions = meshEntry->addChild("shader_options");
             ObjectEntry *shaderOptions = meshEntry->addChild("shader_options");
-            saveShaderOptionsToEntry(shaderOptions, sceneMesh->getMaterial(), sceneMesh->getLocalShaderOptions());
+            
+            // RENDERER_TODO
+            //saveShaderOptionsToEntry(shaderOptions, sceneMesh->getMaterial(), sceneMesh->getLocalShaderOptions());
         }
         }
     }
     }
     
     
@@ -2413,8 +2445,8 @@ void PolycodeEntityEditor::saveEntityToObjectEntry(Entity *entity, ObjectEntry *
 void PolycodeEntityEditor::saveShaderOptionsToEntry(ObjectEntry *entry, Material *material, ShaderBinding *binding) {
 void PolycodeEntityEditor::saveShaderOptionsToEntry(ObjectEntry *entry, Material *material, ShaderBinding *binding) {
 
 
 	
 	
-    if(material->getNumShaders() > 0) {
-        for(int s=0; s < material->getNumShaders(); s++) {
+    if(material->getNumShaderPasses() > 0) {
+        for(int s=0; s < material->getNumShaderPasses(); s++) {
             Shader *shader = material->getShader(s);
             Shader *shader = material->getShader(s);
             
             
             ObjectEntry *shaderEntry = entry->addChild("shader");
             ObjectEntry *shaderEntry = entry->addChild("shader");

+ 0 - 1
src/ide/PolycodeIDEApp.cpp

@@ -22,7 +22,6 @@
 
 
 #include "polycode/ide/PolycodeIDEApp.h"
 #include "polycode/ide/PolycodeIDEApp.h"
 
 
-
 using namespace Polycode;
 using namespace Polycode;
 
 
 UIGlobalMenu *globalMenu;
 UIGlobalMenu *globalMenu;

+ 4 - 4
src/ide/PolycodeMaterialEditor.cpp

@@ -719,8 +719,8 @@ MaterialPreviewBox::MaterialPreviewBox() : UIElement() {
 	
 	
 	previewBg->setMaterialByName("Unlit");
 	previewBg->setMaterialByName("Unlit");
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("materialEditor/material_grid.png");
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("materialEditor/material_grid.png");
-	if(previewBg->getLocalShaderOptions()) {
-        previewBg->getLocalShaderOptions()->setTextureForParam("diffuse", tex);
+	if(previewBg->getNumShaderPasses() > 0) {
+        previewBg->getShaderPass(0).shaderBinding->setTextureForParam("diffuse", tex);
 	}
 	}
 	previewScene->addChild(previewBg);
 	previewScene->addChild(previewBg);
 	
 	
@@ -1328,8 +1328,8 @@ void PolycodeMaterialEditor::saveMaterials(ObjectEntry *materialsEntry, std::vec
 			}
 			}
 		}
 		}
 		
 		
-		if(material->getNumShaders() > 0) {
-			for(int s=0; s < material->getNumShaders(); s++) { 
+		if(material->getNumShaderPasses() > 0) {
+			for(int s=0; s < material->getNumShaderPasses(); s++) {
 				Shader *shader = material->getShader(s);
 				Shader *shader = material->getShader(s);
 				
 				
 				ObjectEntry *shaderEntry = materialEntry->addChild("shader");
 				ObjectEntry *shaderEntry = materialEntry->addChild("shader");

+ 5 - 5
src/ide/PolycodeProps.cpp

@@ -1243,8 +1243,8 @@ MaterialProp::MaterialProp(const String &caption) : PropProp(caption, "Material"
 	
 	
 	previewBg->setMaterialByName("Unlit");
 	previewBg->setMaterialByName("Unlit");
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("materialEditor/material_grid.png");
 	Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("materialEditor/material_grid.png");
-	if(previewBg->getLocalShaderOptions()) {
-        previewBg->getLocalShaderOptions()->setTextureForParam("diffuse", tex);
+	if(previewBg->getNumShaderPasses()) {
+        previewBg->getShaderPass(0).shaderBinding->setTextureForParam("diffuse", tex);
 	}
 	}
 	previewScene->addChild(previewBg);
 	previewScene->addChild(previewBg);
 	
 	
@@ -1634,7 +1634,7 @@ void ShaderPassProp::handleEvent(Event *event) {
 		Shader *selectedShader = (Shader*)shaderComboBox->getSelectedItem()->data;
 		Shader *selectedShader = (Shader*)shaderComboBox->getSelectedItem()->data;
 		if(selectedShader) {
 		if(selectedShader) {
 			if(material->getShader(shaderIndex) != selectedShader) {
 			if(material->getShader(shaderIndex) != selectedShader) {
-				material->removeShader(shaderIndex);				
+				material->removeShaderPass(shaderIndex);
                 ShaderBinding *newShaderBinding = new ShaderBinding();
                 ShaderBinding *newShaderBinding = new ShaderBinding();
 				material->addShaderAtIndex(selectedShader, newShaderBinding, shaderIndex);
 				material->addShaderAtIndex(selectedShader, newShaderBinding, shaderIndex);
 				dispatchEvent(new Event(), Event::CHANGE_EVENT);
 				dispatchEvent(new Event(), Event::CHANGE_EVENT);
@@ -1925,7 +1925,7 @@ void ShaderPassesSheet::refreshPasses() {
 		return;
 		return;
 	}
 	}
 
 
-	for(int i=0; i < material->getNumShaders(); i++) {
+	for(int i=0; i < material->getNumShaderPasses(); i++) {
 		ShaderPassProp *passProp = new ShaderPassProp(material, i);
 		ShaderPassProp *passProp = new ShaderPassProp(material, i);
 		passProp->addEventListener(this, Event::REMOVE_EVENT);
 		passProp->addEventListener(this, Event::REMOVE_EVENT);
 		passProp->addEventListener(this, Event::CHANGE_EVENT);		
 		passProp->addEventListener(this, Event::CHANGE_EVENT);		
@@ -1940,7 +1940,7 @@ void ShaderPassesSheet::refreshPasses() {
 
 
 void ShaderPassesSheet::Update() {
 void ShaderPassesSheet::Update() {
 	if(removeIndex != -1) {
 	if(removeIndex != -1) {
-		material->removeShader(removeIndex);
+		material->removeShaderPass(removeIndex);
 		refreshPasses();
 		refreshPasses();
 		removeIndex = -1;			
 		removeIndex = -1;			
 	}
 	}

+ 7 - 7
src/ide/PolycodeSpriteEditor.cpp

@@ -33,7 +33,7 @@ SpriteSheetEditor::SpriteSheetEditor(SpriteSet *sprite) : UIElement() {
     this->sprite = sprite;
     this->sprite = sprite;
     willCreateFrame = false;
     willCreateFrame = false;
     zoomScale = 1.0;
     zoomScale = 1.0;
-    enableScissor = true;
+    drawCall.options.enableScissor = true;
     
     
     previewBg = new UIImage("main/grid_dark.png");
     previewBg = new UIImage("main/grid_dark.png");
     addChild(previewBg);
     addChild(previewBg);
@@ -56,14 +56,14 @@ SpriteSheetEditor::SpriteSheetEditor(SpriteSet *sprite) : UIElement() {
     frameVisualizerMesh->setColor(1.0, 1.0, 1.0, 1.0);
     frameVisualizerMesh->setColor(1.0, 1.0, 1.0, 1.0);
     addChild(frameVisualizerMesh);
     addChild(frameVisualizerMesh);
     frameVisualizerMesh->setAnchorPoint(-1.0, -1.0, 0.0);
     frameVisualizerMesh->setAnchorPoint(-1.0, -1.0, 0.0);
-    frameVisualizerMesh->getLocalShaderOptions()->loadTextureForParam("diffuse", "main/stipple.png");
+    frameVisualizerMesh->getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", "main/stipple.png");
     frameVisualizerMesh->lineWidth = 1; //CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX();
     frameVisualizerMesh->lineWidth = 1; //CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX();
 
 
     frameVisualizerMeshSelected = new SceneMesh(Mesh::LINE_MESH);
     frameVisualizerMeshSelected = new SceneMesh(Mesh::LINE_MESH);
     frameVisualizerMeshSelected->setColor(1.0, 1.0, 0.0, 1.0);
     frameVisualizerMeshSelected->setColor(1.0, 1.0, 0.0, 1.0);
     addChild(frameVisualizerMeshSelected);
     addChild(frameVisualizerMeshSelected);
     frameVisualizerMeshSelected->setAnchorPoint(-1.0, -1.0, 0.0);
     frameVisualizerMeshSelected->setAnchorPoint(-1.0, -1.0, 0.0);
-    frameVisualizerMeshSelected->getLocalShaderOptions()->loadTextureForParam("diffuse", "main/stipple.png");
+    frameVisualizerMeshSelected->getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", "main/stipple.png");
     frameVisualizerMeshSelected->lineWidth = 2;
     frameVisualizerMeshSelected->lineWidth = 2;
     
     
     previewImage->setTexture(sprite->getTexture());
     previewImage->setTexture(sprite->getTexture());
@@ -1131,7 +1131,7 @@ void SpriteStateEditBar::refreshBar() {
         return;
         return;
     }
     }
     
     
-    barMesh->getLocalShaderOptions()->setTextureForParam("diffuse", spriteSet->getTexture());
+    barMesh->getShaderPass(0).shaderBinding->setTextureForParam("diffuse", spriteSet->getTexture());
     
     
     Mesh *mesh = barMesh->getMesh();
     Mesh *mesh = barMesh->getMesh();
     mesh->clearMesh();
     mesh->clearMesh();
@@ -1339,7 +1339,7 @@ SpriteStateEditBar::SpriteStateEditBar(SpriteSet *spriteSet) : UIElement() {
     
     
     barMeshBg = new SceneMesh(Mesh::TRI_MESH);
     barMeshBg = new SceneMesh(Mesh::TRI_MESH);
     barBase->addChild(barMeshBg);
     barBase->addChild(barMeshBg);
-    barMeshBg->getLocalShaderOptions()->loadTextureForParam("diffuse", "spriteEditor/sprite_frame_bg.png");
+    barMeshBg->getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", "spriteEditor/sprite_frame_bg.png");
     barMeshBg->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     barMeshBg->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     
     
     barMesh = new SceneMesh(Mesh::TRI_MESH);
     barMesh = new SceneMesh(Mesh::TRI_MESH);
@@ -1352,7 +1352,7 @@ SpriteStateEditBar::SpriteStateEditBar(SpriteSet *spriteSet) : UIElement() {
     frameGripsMesh = new SceneMesh(Mesh::TRI_MESH);
     frameGripsMesh = new SceneMesh(Mesh::TRI_MESH);
     barBase->addChild(frameGripsMesh);
     barBase->addChild(frameGripsMesh);
     frameGripsMesh->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     frameGripsMesh->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
-    frameGripsMesh->getLocalShaderOptions()->loadTextureForParam("diffuse", "spriteEditor/frame_grip.png");
+    frameGripsMesh->getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", "spriteEditor/frame_grip.png");
     
     
     this->addEventListener(this, InputEvent::EVENT_MOUSEWHEEL_UP);
     this->addEventListener(this, InputEvent::EVENT_MOUSEWHEEL_UP);
     this->addEventListener(this, InputEvent::EVENT_MOUSEWHEEL_DOWN);
     this->addEventListener(this, InputEvent::EVENT_MOUSEWHEEL_DOWN);
@@ -1936,7 +1936,7 @@ SpritePreview::SpritePreview(SpriteSet *spriteSet) : UIElement() {
     
     
     boundingBoxPreview = new SceneMesh(Mesh::LINE_MESH);
     boundingBoxPreview = new SceneMesh(Mesh::LINE_MESH);
     addChild(boundingBoxPreview);
     addChild(boundingBoxPreview);
-    boundingBoxPreview->getLocalShaderOptions()->loadTextureForParam("diffuse", "main/stipple_small.png");
+    boundingBoxPreview->getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", "main/stipple_small.png");
     boundingBoxPreview->lineWidth = 1;
     boundingBoxPreview->lineWidth = 1;
     
     
     
     

+ 35 - 14
src/ide/TransformGizmo.cpp

@@ -281,7 +281,9 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
     yLine->setLocalBoundingBox(yLine->getMesh()->calculateBBox());
     yLine->setLocalBoundingBox(yLine->getMesh()->calculateBBox());
     yLine->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
     yLine->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
 	transformAndScaleLines->addChild(yLine);
 	transformAndScaleLines->addChild(yLine);
-
+    yLine->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    yLine->setForceMaterial(true);
+    
 	xLine = new SceneMesh(Mesh::LINE_MESH);
 	xLine = new SceneMesh(Mesh::LINE_MESH);
 	xLine->getMesh()->addVertex(0.0, 0.0, 0.0);
 	xLine->getMesh()->addVertex(0.0, 0.0, 0.0);
 	xLine->getMesh()->addVertex(1.0, 0.0, 0.0);
 	xLine->getMesh()->addVertex(1.0, 0.0, 0.0);
@@ -290,7 +292,9 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
     xLine->setLocalBoundingBox(xLine->getMesh()->calculateBBox());
     xLine->setLocalBoundingBox(xLine->getMesh()->calculateBBox());
     xLine->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
     xLine->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
 	transformAndScaleLines->addChild(xLine);
 	transformAndScaleLines->addChild(xLine);
-
+    xLine->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    xLine->setForceMaterial(true);
+    
 	zLine = new SceneMesh(Mesh::LINE_MESH);
 	zLine = new SceneMesh(Mesh::LINE_MESH);
 	zLine->getMesh()->addVertex(0.0, 0.0, 0.0);
 	zLine->getMesh()->addVertex(0.0, 0.0, 0.0);
 	zLine->getMesh()->addVertex(0.0, 0.0, 1.0);
 	zLine->getMesh()->addVertex(0.0, 0.0, 1.0);
@@ -299,7 +303,9 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
     zLine->setLocalBoundingBox(zLine->getMesh()->calculateBBox());
     zLine->setLocalBoundingBox(zLine->getMesh()->calculateBBox());
     zLine->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
     zLine->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
 	transformAndScaleLines->addChild(zLine);
 	transformAndScaleLines->addChild(zLine);
-	
+    zLine->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    zLine->setForceMaterial(true);
+    
 	// MOVE
 	// MOVE
 	
 	
 	yArrow = new ScenePrimitive(ScenePrimitive::TYPE_CONE, 0.2, 0.05, 12);
 	yArrow = new ScenePrimitive(ScenePrimitive::TYPE_CONE, 0.2, 0.05, 12);
@@ -307,21 +313,24 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
 	yArrow->setPosition(0.0, 1.0, 0.0);
 	yArrow->setPosition(0.0, 1.0, 0.0);
 	yArrow->depthTest = false;
 	yArrow->depthTest = false;
 	trasnformDecorators->addChild(yArrow);
 	trasnformDecorators->addChild(yArrow);
-	
+    yArrow->setForceMaterial(true);
+    
 	xArrow = new ScenePrimitive(ScenePrimitive::TYPE_CONE, 0.2, 0.05, 12);
 	xArrow = new ScenePrimitive(ScenePrimitive::TYPE_CONE, 0.2, 0.05, 12);
 	xArrow->setColor(1.0, 0.0, 0.0, 1.0);
 	xArrow->setColor(1.0, 0.0, 0.0, 1.0);
 	xArrow->setPosition(1.0, 0.0, 0.0);
 	xArrow->setPosition(1.0, 0.0, 0.0);
 	xArrow->Roll(-90);
 	xArrow->Roll(-90);
 	xArrow->depthTest = false;
 	xArrow->depthTest = false;
 	trasnformDecorators->addChild(xArrow);
 	trasnformDecorators->addChild(xArrow);
-
+    xArrow->setForceMaterial(true);
+    
 	zArrow = new ScenePrimitive(ScenePrimitive::TYPE_CONE, 0.2, 0.05, 12);
 	zArrow = new ScenePrimitive(ScenePrimitive::TYPE_CONE, 0.2, 0.05, 12);
 	zArrow->setColor(0.0, 0.0, 1.0, 1.0);
 	zArrow->setColor(0.0, 0.0, 1.0, 1.0);
 	zArrow->setPosition(0.0, 0.0, 1.0);
 	zArrow->setPosition(0.0, 0.0, 1.0);
 	zArrow->Pitch(90);
 	zArrow->Pitch(90);
 	zArrow->depthTest = false;	
 	zArrow->depthTest = false;	
 	trasnformDecorators->addChild(zArrow);
 	trasnformDecorators->addChild(zArrow);
-
+    zArrow->setForceMaterial(true);
+    
 	// SCALE
 	// SCALE
 
 
 	yBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.1, 0.1, 0.1);
 	yBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.1, 0.1, 0.1);
@@ -329,21 +338,24 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
 	yBox->setPosition(0.0, 1.0, 0.0);
 	yBox->setPosition(0.0, 1.0, 0.0);
 	yBox->depthTest = false;
 	yBox->depthTest = false;
 	scaleDecorators->addChild(yBox);
 	scaleDecorators->addChild(yBox);
-	
+    yBox->setForceMaterial(true);
+    
 	xBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.1, 0.1, 0.1);
 	xBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.1, 0.1, 0.1);
 	xBox->setColor(1.0, 0.0, 0.0, 1.0);
 	xBox->setColor(1.0, 0.0, 0.0, 1.0);
 	xBox->setPosition(1.0, 0.0, 0.0);
 	xBox->setPosition(1.0, 0.0, 0.0);
 	xBox->Roll(-90);
 	xBox->Roll(-90);
 	xBox->depthTest = false;
 	xBox->depthTest = false;
 	scaleDecorators->addChild(xBox);
 	scaleDecorators->addChild(xBox);
-
+    xBox->setForceMaterial(true);
+    
 	zBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.1, 0.1, 0.1);
 	zBox = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 0.1, 0.1, 0.1);
 	zBox->setColor(0.0, 0.0, 1.0, 1.0);
 	zBox->setColor(0.0, 0.0, 1.0, 1.0);
 	zBox->setPosition(0.0, 0.0, 1.0);
 	zBox->setPosition(0.0, 0.0, 1.0);
 	zBox->Pitch(90);
 	zBox->Pitch(90);
 	zBox->depthTest = false;	
 	zBox->depthTest = false;	
 	scaleDecorators->addChild(zBox);
 	scaleDecorators->addChild(zBox);
-
+    zBox->setForceMaterial(true);
+    
 	// ROTATE
 	// ROTATE
 
 
 	bgCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.6, 2.6, 32);
 	bgCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.6, 2.6, 32);
@@ -353,7 +365,9 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
 	bgCircle->billboardMode = true;
 	bgCircle->billboardMode = true;
 	rotateDectorators->addChild(bgCircle);
 	rotateDectorators->addChild(bgCircle);
     bgCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX());
     bgCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX());
-
+    bgCircle->setForceMaterial(true);
+    bgCircle->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    
 	outerCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 3.0, 3.0, 32);
 	outerCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 3.0, 3.0, 32);
 	outerCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	outerCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	outerCircle->setColor(1.0, 1.0, 1.0, 1.0);
 	outerCircle->setColor(1.0, 1.0, 1.0, 1.0);
@@ -361,8 +375,10 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
 	outerCircle->billboardMode = true;
 	outerCircle->billboardMode = true;
 	rotateDectorators->addChild(outerCircle);
 	rotateDectorators->addChild(outerCircle);
     outerCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
     outerCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
+    outerCircle->setForceMaterial(true);
+    outerCircle->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     
     
-	pitchCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.55, 2.55, 32);
+	pitchCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.55, 2.55, 64);
 	pitchCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	pitchCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	pitchCircle->setColor(1.0, 0.0, 0.0, 1.0);
 	pitchCircle->setColor(1.0, 0.0, 0.0, 1.0);
 	pitchCircle->depthTest = false;
 	pitchCircle->depthTest = false;
@@ -370,8 +386,10 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
 	rotateDectorators->addChild(pitchCircle);
 	rotateDectorators->addChild(pitchCircle);
 	pitchCircle->setMaterialByName("OneSidedLine");
 	pitchCircle->setMaterialByName("OneSidedLine");
     pitchCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
     pitchCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX() * 2.0);
+    pitchCircle->setForceMaterial(true);
+    pitchCircle->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     
     
-	yawCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.65, 2.65, 32);
+	yawCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.65, 2.65, 64);
 	yawCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	yawCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	yawCircle->setColor(0.0, 1.0, 0.0, 1.0);
 	yawCircle->setColor(0.0, 1.0, 0.0, 1.0);
 	yawCircle->depthTest = false;
 	yawCircle->depthTest = false;
@@ -379,16 +397,19 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
 	rotateDectorators->addChild(yawCircle);
 	rotateDectorators->addChild(yawCircle);
 	yawCircle->setMaterialByName("OneSidedLine");
 	yawCircle->setMaterialByName("OneSidedLine");
     yawCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX()* 2.0);
     yawCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX()* 2.0);
+    yawCircle->setForceMaterial(true);
+    yawCircle->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     
     
-	rollCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.6, 2.6, 32);
+	rollCircle = new ScenePrimitive(ScenePrimitive::TYPE_LINE_CIRCLE, 2.6, 2.6, 64);
 	rollCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	rollCircle->getMesh()->setMeshType(Mesh::LINE_LOOP_MESH);
 	rollCircle->setColor(0.0, 0.0, 1.0, 1.0);
 	rollCircle->setColor(0.0, 0.0, 1.0, 1.0);
 	rollCircle->depthTest = false;
 	rollCircle->depthTest = false;
 	rotateDectorators->addChild(rollCircle);
 	rotateDectorators->addChild(rollCircle);
 	rollCircle->setMaterialByName("OneSidedLine");
 	rollCircle->setMaterialByName("OneSidedLine");
     rollCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX()* 2.0);
     rollCircle->setLineWidth(CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX()* 2.0);
+    rollCircle->setForceMaterial(true);
+    rollCircle->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
     
     
-	
 	rotateDectorators->processInputEvents = true;
 	rotateDectorators->processInputEvents = true;
 	
 	
 	//pitchGrip = new ScenePrimitive(ScenePrimitive::TYPE_TORUS, 1.55 * 0.5, 0.05, 16, 3);
 	//pitchGrip = new ScenePrimitive(ScenePrimitive::TYPE_TORUS, 1.55 * 0.5, 0.05, 16, 3);

+ 34 - 23
src/modules/ui/PolyUIElement.cpp

@@ -164,7 +164,6 @@ Label *UILabel::getLabel() {
 
 
 UIRect::UIRect(String fileName, Number width, Number height) : UIElement() {
 UIRect::UIRect(String fileName, Number width, Number height) : UIElement() {
 	texture = NULL;
 	texture = NULL;
-    localShaderOptions = NULL;
 	loadTexture(fileName);
 	loadTexture(fileName);
     initRect(width, height);
     initRect(width, height);
     imageWidth = width;
     imageWidth = width;
@@ -173,7 +172,6 @@ UIRect::UIRect(String fileName, Number width, Number height) : UIElement() {
 
 
 UIRect::UIRect(String fileName) : UIElement() {
 UIRect::UIRect(String fileName) : UIElement() {
 	texture = NULL;
 	texture = NULL;
-    localShaderOptions = NULL;
 	loadTexture(fileName);
 	loadTexture(fileName);
 	if(texture) {	
 	if(texture) {	
 		initRect(texture->getWidth(), texture->getHeight());
 		initRect(texture->getWidth(), texture->getHeight());
@@ -190,7 +188,6 @@ UIRect::UIRect(String fileName) : UIElement() {
 
 
 UIRect::UIRect(Number width, Number height) : UIElement() {
 UIRect::UIRect(Number width, Number height) : UIElement() {
 	texture = NULL;
 	texture = NULL;
-    localShaderOptions = NULL;
 	initRect(width, height);
 	initRect(width, height);
 	imageWidth = 0;
 	imageWidth = 0;
 	imageHeight = 0;
 	imageHeight = 0;
@@ -263,23 +260,17 @@ void UIRect::initRect(Number width, Number height) {
     rectMesh->addIndexedFace(0, 1, 2);
     rectMesh->addIndexedFace(0, 1, 2);
     rectMesh->addIndexedFace(0, 2, 3);
     rectMesh->addIndexedFace(0, 2, 3);
     
     
-    material =  (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitUntextured");
-    localShaderOptions = new ShaderBinding();
+    setMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitUntextured"));
     
     
-    localShaderOptions->addParamPointer(ProgramParam::PARAM_COLOR, "entityColor", &color);
-    
-    localShaderOptions->addAttributeBinding("texCoord", &rectMesh->vertexTexCoordArray);
-    localShaderOptions->addAttributeBinding("position", &rectMesh->vertexPositionArray);
-
     if(texture) {
     if(texture) {
-        material =  (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Unlit");
-        localShaderOptions->setTextureForParam("diffuse", texture);
+        setMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Unlit"));
+        shaderPasses[0].shaderBinding->setTextureForParam("diffuse", texture);
     }
     }
 }
 }
 
 
 UIRect::~UIRect() {
 UIRect::~UIRect() {
 	delete rectMesh;
 	delete rectMesh;
-    delete localShaderOptions;
+    delete shaderPasses[0].shaderBinding;
 }
 }
 
 
 void UIRect::loadTexture(String fileName) {
 void UIRect::loadTexture(String fileName) {
@@ -290,29 +281,49 @@ void UIRect::loadTexture(String fileName) {
 	texture = materialManager->createTextureFromFile(fileName, materialManager->clampDefault, false);
 	texture = materialManager->createTextureFromFile(fileName, materialManager->clampDefault, false);
     
     
     if(!texture) {
     if(!texture) {
-        material =  (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitUntextured");
+        setMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitUntextured"));
     } else {
     } else {
-        material =  (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Unlit");
+        setMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Unlit"));
     }
     }
     
     
-    if(localShaderOptions) {
-        localShaderOptions->setTextureForParam("diffuse", texture);
+    if(shaderPasses.size() > 0) {
+        shaderPasses[0].shaderBinding->setTextureForParam("diffuse", texture);
     }
     }
 }
 }
 
 
 void UIRect::setTexture(Texture *texture) {
 void UIRect::setTexture(Texture *texture) {
     
     
     if(!texture) {
     if(!texture) {
-        material =  (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitUntextured");
+        setMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "UnlitUntextured"));
     } else {
     } else {
-        material =  (Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Unlit");
+        setMaterial((Material*)CoreServices::getInstance()->getResourceManager()->getGlobalPool()->getResource(Resource::RESOURCE_MATERIAL, "Unlit"));
     }
     }
     
     
 	this->texture = texture;
 	this->texture = texture;
-    if(localShaderOptions) {
-        localShaderOptions->setTextureForParam("diffuse", texture);
+    if(shaderPasses[0].shaderBinding) {
+        shaderPasses[0].shaderBinding->setTextureForParam("diffuse", texture);
+    }
+}
+
+void UIRect::setMaterial(Material *material) {
+    
+    for(int i=0; i < shaderPasses.size(); i++) {
+        delete shaderPasses[i].shaderBinding;
     }
     }
-}	
+    shaderPasses.clear();
+    
+    this->material = material;
+    
+    ShaderPass pass;
+    pass.shaderBinding = new ShaderBinding();
+    pass.shader = material->getShaderPass(0).shader;
+    shaderPasses.push_back(pass);
+    
+    shaderPasses[0].shaderBinding->addParamPointer(ProgramParam::PARAM_COLOR, "entityColor", &color);
+    shaderPasses[0].shaderBinding->addAttributeBinding("texCoord", &rectMesh->vertexTexCoordArray);
+    shaderPasses[0].shaderBinding->addAttributeBinding("position", &rectMesh->vertexPositionArray);
+    
+}
 
 
 Texture *UIRect::getTexture() {
 Texture *UIRect::getTexture() {
 	return texture;
 	return texture;
@@ -334,7 +345,7 @@ void UIRect::Render(GPUDrawBuffer *buffer) {
     }
     }
     
     
     drawCall.material = material;
     drawCall.material = material;
-    drawCall.shaderBinding = localShaderOptions;
+    drawCall.shaderPasses = shaderPasses;
     
     
     buffer->drawCalls.push_back(drawCall);
     buffer->drawCalls.push_back(drawCall);
 }
 }