Browse Source

New material editor, started on shader editor (doesnt save yet), rewrote some internal shader stuff to be more streamlined, fixed Label not redrawing correctly after setting size or font, fix for paths with spaces in executeExternalCommand and IDE on Linux and Mac, made 2D template use an entity2d file, fixed new file and new project dialog buttons firing while invisible

Ivan Safrin 12 years ago
parent
commit
403c82ffdb
29 changed files with 564 additions and 200 deletions
  1. 1 15
      Core/Contents/Include/PolyGLSLProgram.h
  2. 6 5
      Core/Contents/Include/PolyGLSLShader.h
  3. 5 4
      Core/Contents/Include/PolyGLSLShaderModule.h
  4. 2 2
      Core/Contents/Include/PolyLabel.h
  5. 6 3
      Core/Contents/Include/PolyMaterialManager.h
  6. 2 1
      Core/Contents/Include/PolyModule.h
  7. 26 1
      Core/Contents/Include/PolyShader.h
  8. 1 1
      Core/Contents/Source/PolyCocoaCore.mm
  9. 2 79
      Core/Contents/Source/PolyGLSLProgram.cpp
  10. 24 9
      Core/Contents/Source/PolyGLSLShader.cpp
  11. 12 12
      Core/Contents/Source/PolyGLSLShaderModule.cpp
  12. 9 6
      Core/Contents/Source/PolyLabel.cpp
  13. 41 4
      Core/Contents/Source/PolyMaterialManager.cpp
  14. 17 36
      Core/Contents/Source/PolyResourceManager.cpp
  15. 1 1
      Core/Contents/Source/PolySceneLabel.cpp
  16. 1 1
      Core/Contents/Source/PolyScreenLabel.cpp
  17. 87 0
      Core/Contents/Source/PolyShader.cpp
  18. 46 4
      IDE/Contents/Include/PolycodeMaterialEditor.h
  19. BIN
      IDE/Contents/Resources/Images/material_icon.png
  20. BIN
      IDE/Contents/Resources/Images/new_material.png
  21. BIN
      IDE/Contents/Resources/Images/new_shader.png
  22. BIN
      IDE/Contents/Resources/Images/shader_icon.png
  23. BIN
      IDE/Contents/Resources/ProjectTemplates/Basic/2D Project/Resources/MyScreen.entity2d
  24. 9 2
      IDE/Contents/Resources/ProjectTemplates/Basic/2D Project/Scripts/Main.lua
  25. 7 7
      IDE/Contents/Resources/ProjectTemplates/Basic/2D Project/template.polyproject
  26. 3 0
      IDE/Contents/Source/NewFileWindow.cpp
  27. 4 0
      IDE/Contents/Source/NewProjectWindow.cpp
  28. 250 5
      IDE/Contents/Source/PolycodeMaterialEditor.cpp
  29. 2 2
      IDE/Contents/Source/PolycodeToolLauncher.cpp

+ 1 - 15
Core/Contents/Include/PolyGLSLProgram.h

@@ -29,26 +29,12 @@ THE SOFTWARE.
 
 namespace Polycode {
 
-class _PolyExport GLSLProgramParam : public ProgramParam {
-	public:		
-		static void createParamData(int *retType, const String& type, const String& value, const String& min, const String& max, void **valueRes, void **minRes, void **maxRes);	
-	};
-
-	class _PolyExport GLSLProgram : public Resource {
+	class _PolyExport GLSLProgram : public ShaderProgram {
 		public:
 			GLSLProgram(int type);
 			virtual ~GLSLProgram();
 			
-			GLSLProgramParam addParam(const String& name, const String& typeString, const String& valueString, bool isAuto, int autoID, int paramType, void *defaultData, void *minData, void *maxData);
-		
 			unsigned int program;
-//			GLSLparameter modelViewProjection;
 	
-			static const int TYPE_VERT = 0;
-			static const int TYPE_FRAG = 1;		
-			
-			int type;
-			
-			std::vector<GLSLProgramParam> params;
 	};
 }

+ 6 - 5
Core/Contents/Include/PolyGLSLShader.h

@@ -49,13 +49,14 @@ namespace Polycode {
 
 			ShaderBinding *createBinding();
 			virtual void reload();
-		
+			
+			void setVertexProgram(ShaderProgram *vp);
+			void setFragmentProgram(ShaderProgram *fp);			
+				
 			unsigned int shader_id;		
-			GLSLProgram *vp;
-			GLSLProgram *fp;			
 			
-		protected:
-			void linkProgram();
+			void linkProgram();			
+			void unlinkProgram();
 	};
 	
 	class _PolyExport GLSLShaderBinding : public ShaderBinding {

+ 5 - 4
Core/Contents/Include/PolyGLSLShaderModule.h

@@ -27,8 +27,9 @@ THE SOFTWARE.
 namespace Polycode {
 	
 	class GLSLProgram;
-	class GLSLProgramParam;
+	class ProgramParam;
 	class GLSLShader;
+	class ShaderProgram;
 
 	class _PolyExport GLSLShaderModule : public PolycodeShaderModule {
 		public:
@@ -36,7 +37,7 @@ namespace Polycode {
 			virtual ~GLSLShaderModule();
 		
 			bool acceptsExtension(const String& extension);
-			Resource* createProgramFromFile(const String& extension, const String& fullPath);
+			ShaderProgram* createProgramFromFile(const String& extension, const String& fullPath);
 			void reloadPrograms();
 			String getShaderType();
 			Shader *createShader(TiXmlNode *node);
@@ -45,10 +46,10 @@ namespace Polycode {
 		
 	protected:
 
-		GLSLProgramParam addParamToProgram(GLSLProgram *program,TiXmlNode *node);		
+		ProgramParam addParamToProgram(GLSLProgram *program,TiXmlNode *node);		
 		void recreateGLSLProgram(GLSLProgram *prog, const String& fileName, int type);
 		GLSLProgram *createGLSLProgram(const String& fileName, int type);
-		void updateGLSLParam(Renderer *renderer, GLSLShader *glslShader, GLSLProgramParam &param, ShaderBinding *materialOptions, ShaderBinding *localOptions);			
+		void updateGLSLParam(Renderer *renderer, GLSLShader *glslShader, ProgramParam &param, ShaderBinding *materialOptions, ShaderBinding *localOptions);			
 		
 		std::vector<GLSLProgram*> programs;
 	};

+ 2 - 2
Core/Contents/Include/PolyLabel.h

@@ -91,7 +91,7 @@ namespace Polycode {
 			int getAntialiasMode() const;			
 			void setAntialiasMode(int newMode);
 			
-			bool colorsChanged();
+			bool optionsChanged();
 					
 			static const int ANTIALIAS_FULL = 0;
 			static const int ANTIALIAS_NONE = 1;
@@ -101,7 +101,7 @@ namespace Polycode {
 			
 		protected:
 		
-			bool _colorsChanged;
+			bool _optionsChanged;
 			GlyphData labelData;
 	
 			std::vector<ColorRange> colorRanges;

+ 6 - 3
Core/Contents/Include/PolyMaterialManager.h

@@ -37,6 +37,7 @@ namespace Polycode {
 	class SceneRenderTexture;
 	class Shader;
 	class String;
+	class ShaderProgram;
 	
 	/**
 	* Manages loading and reloading of materials, textures and shaders. This class should be only accessed from the CoreServices singleton.
@@ -68,6 +69,8 @@ namespace Polycode {
 			//SceneRenderTexture *createRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight);
 			Texture *getTextureByResourcePath(const String& resourcePath) const;
 			
+			ShaderProgram *createProgramFromFile(String programPath);
+			
 			// cubemaps
 		
 			Cubemap *cubemapFromXMLNode(TiXmlNode *node);
@@ -79,12 +82,12 @@ namespace Polycode {
 			
 			Shader *setShaderFromXMLNode(TiXmlNode *node);
 			Shader *createShaderFromXMLNode(TiXmlNode *node);
-			
-			void registerShader(Shader *shader);
 		
 			std::vector<Material*> loadMaterialsFromFile(String fileName);
-		
+			std::vector<Shader*> loadShadersFromFile(String fileName);		
+			
 			void addMaterial(Material *material);
+			void addShader(Shader *shader);
 		
 			unsigned int getNumShaders();
 			Shader *getShaderByIndex(unsigned int index);

+ 2 - 1
Core/Contents/Include/PolyModule.h

@@ -20,6 +20,7 @@ namespace Polycode {
 	class Shader;
 	class ShaderBinding;
 	class Resource;
+	class ShaderProgram;
 	
 	class _PolyExport PolycodeModule : public PolyBase {
 	public:
@@ -46,7 +47,7 @@ namespace Polycode {
 		virtual ~PolycodeShaderModule();
 		
 		virtual bool acceptsExtension(const String& extension) = 0;
-		virtual Resource* createProgramFromFile(const String& extension, const String& fullPath) = 0;
+		virtual ShaderProgram* createProgramFromFile(const String& extension, const String& fullPath) = 0;
 		virtual String getShaderType() = 0;
 		virtual Shader *createShader(TiXmlNode *node) = 0;
 	

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

@@ -54,8 +54,27 @@ namespace Polycode {
 	static const int PARAM_Vector3 = 3;
 	static const int PARAM_Color = 4;
 	
+	static void createParamData(int *retType, const String& type, const String& value, const String& min, const String& max, void **valueRes, void **minRes, void **maxRes);	
+	
+	
 	};	
 
+	class _PolyExport ShaderProgram : public Resource {
+		public:
+			ShaderProgram(int type);
+			virtual ~ShaderProgram();
+			
+			static const int TYPE_VERT = 0;
+			static const int TYPE_FRAG = 1;		
+			
+			int type;
+			
+			std::vector<ProgramParam> params;
+			
+			ProgramParam addParam(const String& name, const String& typeString, const String& valueString, bool isAuto, int autoID, int paramType, void *defaultData, void *minData, void *maxData);
+					
+	};
+
 	class _PolyExport Shader : public Resource {
 		public:
 			Shader(int type);
@@ -67,7 +86,10 @@ namespace Polycode {
 			
 			virtual ShaderBinding *createBinding() = 0;
 			virtual void reload() {}
-
+			
+			virtual void setVertexProgram(ShaderProgram *vp) {}
+			virtual void setFragmentProgram(ShaderProgram *fp) {}
+			
 			static const int FIXED_SHADER = 0;
 			static const int MODULE_SHADER = 1;
 
@@ -80,6 +102,9 @@ namespace Polycode {
 								
 			bool screenShader;
 			
+			ShaderProgram *vp;
+			ShaderProgram *fp;			
+			
 		protected:
 		
 		

+ 1 - 1
Core/Contents/Source/PolyCocoaCore.mm

@@ -219,7 +219,7 @@ String CocoaCore::executeExternalCommand(String command,  String args, String in
 
 	String finalCommand = command+" "+args;
 	if(inDirectory != "") {
-		finalCommand = "cd "+inDirectory+" && "+finalCommand;
+		finalCommand = "cd \""+inDirectory+"\" && "+finalCommand;
 	}
 	
 	FILE *fp = popen(finalCommand.c_str(), "r");

+ 2 - 79
Core/Contents/Source/PolyGLSLProgram.cpp

@@ -55,86 +55,9 @@ extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocation;
 
 using namespace Polycode;
 
-GLSLProgram::GLSLProgram(int type) : Resource(Resource::RESOURCE_PROGRAM) {
-	this->type = type;
+GLSLProgram::GLSLProgram(int type) : ShaderProgram(type) {
 }
 
 GLSLProgram::~GLSLProgram() {
 	glDeleteShader(program);
-}
-
-GLSLProgramParam GLSLProgram::addParam(const String& name, const String& typeString, const String& valueString, bool isAuto, int autoID, int paramType, void *defaultData, void *minData, void *maxData) {
-	GLSLProgramParam newParam;
-	newParam.name = name;
-	newParam.typeString = typeString;
-	newParam.valueString = valueString;	
-	newParam.paramType = paramType;
-	newParam.defaultData = defaultData;
-	newParam.minValue = minData;
-	newParam.maxValue = maxData;
-	newParam.isAuto = isAuto;
-	newParam.autoID = autoID;
-
-	params.push_back(newParam);
-	return newParam;
-}
-
-void GLSLProgramParam::createParamData(int *retType, const String& type, const String& value, const String& min, const String& max, void **valueRes, void **minRes, void **maxRes) {
-		
-		(*valueRes) = NULL;
-		(*minRes) = NULL;
-		(*maxRes) = NULL;
-						
-		if(type == "Number") {
-			*retType = GLSLProgramParam::PARAM_Number;
-			Number *val = new Number();
-			*val = atof(value.c_str());
-			(*valueRes) = (void*)val;
-			
-			val = new Number();
-			*val = atof(min.c_str());
-			(*minRes) = (void*)val;
-
-			val = new Number();
-			*val = atof(max.c_str());
-			(*maxRes) = (void*)val;			
-			
-			return;		
-		} else if(type == "Vector2") {
-			*retType = GLSLProgramParam::PARAM_Vector2;
-			Vector2 *val = new Vector2();
-			(*valueRes) = (void*)val;
-			vector<String> values = value.split(" ");
-			if(values.size() == 2) {
-				val->set(atof(values[0].c_str()), atof(values[1].c_str()));
-			} else {
-				Logger::log("Error: A Vector2 must have 2 values (%d provided)!\n", values.size());
-			}
-			return;				
-		} else if(type == "Vector3") {
-			*retType = GLSLProgramParam::PARAM_Vector3;
-			Vector3 *val = new Vector3();
-			(*valueRes) = (void*)val;
-			vector<String> values = value.split(" ");
-			if(values.size() == 3) {
-				val->set(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str()));
-			} else {
-				Logger::log("Error: A Vector3 must have 3 values (%d provided)!\n", values.size());
-			}
-			return;
-		} else if(type == "Color") {
-			*retType = GLSLProgramParam::PARAM_Color;
-			Color *val = new Color();
-			(*valueRes) = (void*)val;
-			vector<String> values = value.split(" ");
-			if(values.size() == 4) {
-				val->setColor(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str()), atof(values[3].c_str()));
-			} else {
-				Logger::log("Error: A Color must have 4 values (%d provided)!\n", values.size());
-			}
-			return;			
-		} else {
-			*retType = GLSLProgramParam::PARAM_UNKNOWN;
-			(*valueRes) =  NULL;
-		}
-}
+}

+ 24 - 9
Core/Contents/Source/PolyGLSLShader.cpp

@@ -106,7 +106,7 @@ void GLSLShaderBinding::addParam(const String& type, const String& name, const S
 	void *defaultData;
 	void *minData;
 	void *maxData;		
-	GLSLProgramParam::createParamData(&paramType, type, value, "", "", &defaultData,&minData, &maxData);
+	ProgramParam::createParamData(&paramType, type, value, "", "", &defaultData,&minData, &maxData);
 	LocalShaderParam *newParam = new LocalShaderParam;
 	newParam->data = defaultData;
 	newParam->name = name;
@@ -115,14 +115,31 @@ void GLSLShaderBinding::addParam(const String& type, const String& name, const S
 
 void GLSLShader::linkProgram() {
 	shader_id = glCreateProgram();
-    glAttachShader(shader_id, fp->program);
-    glAttachShader(shader_id, vp->program);
-	
-	glBindAttribLocation(shader_id, 6, "vTangent");
-	
+    glAttachShader(shader_id, ((GLSLProgram*)fp)->program);
+    glAttachShader(shader_id, ((GLSLProgram*)vp)->program);	
+	glBindAttribLocation(shader_id, 6, "vTangent");	
     glLinkProgram(shader_id);
 }
 
+void GLSLShader::unlinkProgram() {
+	glDetachShader(shader_id, ((GLSLProgram*)fp)->program);
+    glDetachShader(shader_id, ((GLSLProgram*)vp)->program);
+	glDeleteProgram(shader_id);	
+}
+
+void GLSLShader::setVertexProgram(ShaderProgram *vp) {
+	unlinkProgram();
+	this->vp = vp;
+	linkProgram();
+}
+
+void GLSLShader::setFragmentProgram(ShaderProgram *fp) {
+	unlinkProgram();
+	this->fp = fp;
+	linkProgram();
+}
+
+
 GLSLShader::GLSLShader(GLSLProgram *vp, GLSLProgram *fp) : Shader(Shader::MODULE_SHADER) {
 	this->vp = vp;
 	this->fp = fp;
@@ -136,9 +153,7 @@ void GLSLShader::reload() {
 }
 
 GLSLShader::~GLSLShader() {
-	glDetachShader(shader_id, fp->program);
-    glDetachShader(shader_id, vp->program);
-	glDeleteProgram(shader_id);	
+	unlinkProgram();
 }
 
 ShaderBinding *GLSLShader::createBinding() {

+ 12 - 12
Core/Contents/Source/PolyGLSLShaderModule.cpp

@@ -185,7 +185,7 @@ void GLSLShaderModule::clearShader() {
 	glUseProgram(0);
 }
 
-void GLSLShaderModule::updateGLSLParam(Renderer *renderer, GLSLShader *glslShader, GLSLProgramParam &param, ShaderBinding *materialOptions, ShaderBinding *localOptions) {
+void GLSLShaderModule::updateGLSLParam(Renderer *renderer, GLSLShader *glslShader, ProgramParam &param, ShaderBinding *materialOptions, ShaderBinding *localOptions) {
 	
 		void *paramData = param.defaultData;
 		LocalShaderParam *localParam = materialOptions->getLocalParamByName(param.name);
@@ -199,7 +199,7 @@ void GLSLShaderModule::updateGLSLParam(Renderer *renderer, GLSLShader *glslShade
 		}
 		
 		switch(param.paramType) {
-			case GLSLProgramParam::PARAM_Number:
+			case ProgramParam::PARAM_Number:
 			{
 				Number *fval;			
 				fval = (Number*)paramData;
@@ -207,20 +207,20 @@ void GLSLShaderModule::updateGLSLParam(Renderer *renderer, GLSLShader *glslShade
 				glUniform1f(paramLocation, *fval);
 				break;
 			}
-			case GLSLProgramParam::PARAM_Vector2:
+			case ProgramParam::PARAM_Vector2:
 			{
 				Vector2 *fval2 = (Vector2*)paramData;
 				int paramLocation = glGetUniformLocation(glslShader->shader_id, param.name.c_str());
 				glUniform2f(paramLocation, fval2->x, fval2->y);				break;				
 			}			
-			case GLSLProgramParam::PARAM_Vector3:
+			case ProgramParam::PARAM_Vector3:
 			{
 				Vector3 *fval3 = (Vector3*)paramData;
 				int paramLocation = glGetUniformLocation(glslShader->shader_id, param.name.c_str());
 				glUniform3f(paramLocation, fval3->x,fval3->y,fval3->z);
 				break;				
 			}
-			case GLSLProgramParam::PARAM_Color:
+			case ProgramParam::PARAM_Color:
 			{
 				Color *col = (Color*)paramData;
 				int paramLocation = glGetUniformLocation(glslShader->shader_id, param.name.c_str());
@@ -419,12 +419,12 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
 	GLSLShaderBinding *cgBinding = (GLSLShaderBinding*)material->getShaderBinding(shaderIndex);
 	
 	for(int i=0; i < glslShader->vp->params.size(); i++) {
-		GLSLProgramParam param = glslShader->vp->params[i];
+		ProgramParam param = glslShader->vp->params[i];
 		updateGLSLParam(renderer, glslShader, param, material->getShaderBinding(shaderIndex), localOptions);
 	}
 	
 	for(int i=0; i < glslShader->fp->params.size(); i++) {
-		GLSLProgramParam param = glslShader->fp->params[i];
+		ProgramParam param = glslShader->fp->params[i];
 		updateGLSLParam(renderer, glslShader, param, material->getShaderBinding(shaderIndex), localOptions);
 	}	
 	
@@ -460,17 +460,17 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
 	return true;
 }
 
-GLSLProgramParam GLSLShaderModule::addParamToProgram(GLSLProgram *program,TiXmlNode *node) {
+ProgramParam GLSLShaderModule::addParamToProgram(GLSLProgram *program,TiXmlNode *node) {
 		bool isAuto = false;
 		int autoID = 0;
-		int paramType = GLSLProgramParam::PARAM_UNKNOWN;
+		int paramType = ProgramParam::PARAM_UNKNOWN;
 		void *defaultData = NULL;
 		void *minData = NULL;
 		void *maxData = NULL;
 		
 		TiXmlElement *nodeElement = node->ToElement();
 		if (!nodeElement) {
-			GLSLProgramParam::createParamData(&paramType, "Number", "0.0", "0.0", "0.0", &defaultData, &minData, &maxData);		
+			ProgramParam::createParamData(&paramType, "Number", "0.0", "0.0", "0.0", &defaultData, &minData, &maxData);		
 			return program->addParam("Unknown", "Number", nodeElement->Attribute("default"), isAuto, autoID, paramType, defaultData, minData, maxData); // Skip comment nodes
 		}
 
@@ -482,7 +482,7 @@ GLSLProgramParam GLSLShaderModule::addParamToProgram(GLSLProgram *program,TiXmlN
 			}
 		}
 		
-		GLSLProgramParam::createParamData(&paramType, nodeElement->Attribute("type"), nodeElement->Attribute("default"), nodeElement->Attribute("min"), nodeElement->Attribute("max"), &defaultData, &minData, &maxData);
+		ProgramParam::createParamData(&paramType, nodeElement->Attribute("type"), nodeElement->Attribute("default"), nodeElement->Attribute("min"), nodeElement->Attribute("max"), &defaultData, &minData, &maxData);
 		
 		return program->addParam(nodeElement->Attribute("name"), nodeElement->Attribute("type"), nodeElement->Attribute("default"), isAuto, autoID, paramType, defaultData, minData, maxData);
 }
@@ -538,7 +538,7 @@ GLSLProgram *GLSLShaderModule::createGLSLProgram(const String& fileName, int typ
 	return prog;
 }
 
-Resource* GLSLShaderModule::createProgramFromFile(const String& extension, const String& fullPath) {
+ShaderProgram* GLSLShaderModule::createProgramFromFile(const String& extension, const String& fullPath) {
 	if(extension == "vert") {
 		Logger::log("Adding GLSL vertex program %s\n", fullPath.c_str());				
 		return createGLSLProgram(fullPath, GLSLProgram::TYPE_VERT);

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

@@ -58,7 +58,7 @@ ColorRange::ColorRange(Color color, unsigned int rangeStart, unsigned int rangeE
 }
 
 
-Label::Label(Font *font, const String& text, int size, int antiAliasMode, bool premultiplyAlpha) : Image(), _colorsChanged(false) {
+Label::Label(Font *font, const String& text, int size, int antiAliasMode, bool premultiplyAlpha) : Image(), _optionsChanged(false) {
 		setPixelType(Image::IMAGE_RGBA);
 		this->font = font;
 		this->size = size;
@@ -78,6 +78,7 @@ unsigned int Label::getSize() const {
 
 void Label::setSize(int newSize) {
 	size = newSize;
+	_optionsChanged	= true;
 }
 
 int Label::getAntialiasMode() const {
@@ -86,6 +87,7 @@ int Label::getAntialiasMode() const {
 
 void Label::setAntialiasMode(int newMode) {
 	antiAliasMode = newMode;
+	_optionsChanged	= true;	
 }
 
 int Label::getTextWidthForString(const String& text) {
@@ -185,6 +187,7 @@ void Label::setFont(Font *newFont) {
 	if(!newFont)
 		return;
 	font = newFont;
+	_optionsChanged	= true;	
 }
 
 const String& Label::getText() const {
@@ -193,12 +196,12 @@ const String& Label::getText() const {
 
 void Label::clearColors() {
 	colorRanges.clear();
-	_colorsChanged = true;
+	_optionsChanged = true;
 }
 
 void Label::setColorForRange(Color color, unsigned int rangeStart, unsigned int rangeEnd) {
 	colorRanges.push_back(ColorRange(color, rangeStart, rangeEnd));
-	_colorsChanged = true;	
+	_optionsChanged = true;	
 }
 
 Color Label::getColorForIndex(unsigned int index) {
@@ -396,8 +399,8 @@ void Label::renderGlyphs(GlyphData *glyphData) {
 	}
 }
 
-bool Label::colorsChanged() {
-	return _colorsChanged;
+bool Label::optionsChanged() {
+	return _optionsChanged;
 }
 
 void Label::setText(const String& text) {
@@ -423,5 +426,5 @@ void Label::setText(const String& text) {
 	
 	createEmpty(textWidth,textHeight);	
 	renderGlyphs(&labelData);
-	_colorsChanged = false;	
+	_optionsChanged = false;	
 }

+ 41 - 4
Core/Contents/Source/PolyMaterialManager.cpp

@@ -80,6 +80,19 @@ void MaterialManager::reloadPrograms() {
 	}
 }
 
+ShaderProgram *MaterialManager::createProgramFromFile(String programPath) {
+	OSFileEntry entry(programPath, OSFileEntry::TYPE_FILE);
+	
+	for(int m=0; m < shaderModules.size(); m++) {
+		PolycodeShaderModule *shaderModule = shaderModules[m];
+		if(shaderModule->acceptsExtension(entry.extension)) {
+			ShaderProgram *newProgram = shaderModule->createProgramFromFile(entry.extension, entry.fullPath);
+			return newProgram;
+		}
+	}
+	return NULL;
+}
+
 void MaterialManager::addShaderModule(PolycodeShaderModule *module) {
 	shaderModules.push_back(module);
 }
@@ -150,10 +163,6 @@ void MaterialManager::reloadTextures() {
 	}
 }
 
-void MaterialManager::registerShader(Shader *shader) {
-	shaders.push_back(shader);
-}
-
 unsigned int MaterialManager::getNumShaders() {
 	return shaders.size();
 }
@@ -270,6 +279,34 @@ void MaterialManager::addMaterial(Material *material) {
 	materials.push_back(material);
 }
 
+void MaterialManager::addShader(Shader *shader) {
+	shaders.push_back(shader);
+}
+
+std::vector<Shader*> MaterialManager::loadShadersFromFile(String fileName) {
+	std::vector<Shader*> retVector;
+	
+	TiXmlDocument doc(fileName.c_str());
+	doc.LoadFile();
+	
+	if(doc.Error()) {
+		Logger::log("XML Error: %s\n", doc.ErrorDesc());
+	} else {
+		TiXmlElement *mElem = doc.RootElement()->FirstChildElement("shaders");
+		if(mElem) {
+			TiXmlNode* pChild;					
+			for (pChild = mElem->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {	
+				Shader *newShader = createShaderFromXMLNode(pChild);
+				if(newShader != NULL) {
+					Logger::log("Adding shader %s\n", newShader->getName().c_str());
+					retVector.push_back(newShader);
+				}
+			}
+		}
+	}
+	return retVector;
+}
+
 std::vector<Material*> MaterialManager::loadMaterialsFromFile(String fileName) {
 	std::vector<Material*> retVector;
 	

+ 17 - 36
Core/Contents/Source/PolyResourceManager.cpp

@@ -58,26 +58,13 @@ void ResourceManager::parseShaders(const String& dirPath, bool recursive) {
 	for(int i=0; i < resourceDir.size(); i++) {	
 		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
 			if(resourceDir[i].extension == "mat") {
-				Logger::log("Adding shaders from %s\n", resourceDir[i].nameWithoutExtension.c_str());
-				TiXmlDocument doc(resourceDir[i].fullPath.c_str());
-				doc.LoadFile();
-				if(doc.Error()) {
-					Logger::log("XML Error: %s\n", doc.ErrorDesc());
-				} else {
-					TiXmlElement *mElem = doc.RootElement()->FirstChildElement("shaders");
-					
-					if(mElem) {
-						TiXmlNode* pChild;					
-						for (pChild = mElem->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {						
-							Shader *newShader = CoreServices::getInstance()->getMaterialManager()->createShaderFromXMLNode(pChild);
-							if(newShader != NULL) {
-								Logger::log("Adding shader %s\n", newShader->getName().c_str());
-								newShader->setResourceName(newShader->getName());
-								resources.push_back(newShader);
-								 CoreServices::getInstance()->getMaterialManager()->registerShader(newShader);
-							}
-						}
-					}
+				MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
+				std::vector<Shader*> shaders = materialManager->loadShadersFromFile(resourceDir[i].fullPath);
+				
+				for(int s=0; s < shaders.size(); s++) {
+					shaders[s]->setResourceName(shaders[s]->getName());
+					resources.push_back(shaders[s]);
+					materialManager->addShader(shaders[s]);
 				}
 			}
 		} else {
@@ -96,17 +83,14 @@ void ResourceManager::parsePrograms(const String& dirPath, bool recursive) {
 	resourceDir = OSBasics::parseFolder(dirPath, false);
 	for(int i=0; i < resourceDir.size(); i++) {	
 		if(resourceDir[i].type == OSFileEntry::TYPE_FILE) {
-			for(int m=0; m < shaderModules.size(); m++) {
-				PolycodeShaderModule *shaderModule = shaderModules[m];
-				if(shaderModule->acceptsExtension(resourceDir[i].extension)) {
-					Resource *newProgram = shaderModule->createProgramFromFile(resourceDir[i].extension, resourceDir[i].fullPath);
-					if(newProgram) {
-						newProgram->setResourceName(resourceDir[i].name);
-						newProgram->setResourcePath(resourceDir[i].fullPath);				
-						resources.push_back(newProgram);					
-					}
-				}
-			}
+			MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
+			
+			ShaderProgram *newProgram = materialManager->createProgramFromFile(resourceDir[i].fullPath);
+			if(newProgram) {
+				newProgram->setResourceName(resourceDir[i].name);
+				newProgram->setResourcePath(resourceDir[i].fullPath);
+				resources.push_back(newProgram);					
+			}			
 		} else {
 			if(recursive)
 				parsePrograms(dirPath+"/"+resourceDir[i].name, true);
@@ -261,12 +245,9 @@ Resource *ResourceManager::getResource(int resourceType, const String& resourceN
 	return NULL;
 }
 
-// Would it make more sense to pass back, like, something like an ObjectEntry here? Lua hates vectors.
-vector<Resource *> ResourceManager::getResources(int resourceType) {
-	vector<Resource *> result;
-	Logger::log("requested all of type %d\n", resourceType);
+std::vector<Resource*> ResourceManager::getResources(int resourceType) {
+	std::vector<Resource*> result;
 	for(int i =0; i < resources.size(); i++) {
-		//		Logger::log("is it %s?\n", resources[i]->getResourceName().c_str());		
 		if(resources[i]->getResourceType() == resourceType) {
 			result.push_back(resources[i]);
 		}

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

@@ -47,7 +47,7 @@ Label *SceneLabel::getLabel() {
 
 void SceneLabel::setText(const String& newText) {
 	
-	if(newText == label->getText() && !label->colorsChanged()) {
+	if(newText == label->getText() && !label->optionsChanged()) {
 		return;
 	}
 

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

@@ -93,7 +93,7 @@ void ScreenLabel::Render() {
 }
 
 void ScreenLabel::setText(const String& newText) {
-	if(newText != label->getText() || label->colorsChanged()) {
+	if(newText != label->getText() || label->optionsChanged()) {
 		label->setText(newText);	
 		updateTexture();
 	}

+ 87 - 0
Core/Contents/Source/PolyShader.cpp

@@ -24,6 +24,91 @@
 
 using namespace Polycode;
 
+ShaderProgram::ShaderProgram(int type) : Resource(Resource::RESOURCE_PROGRAM) {
+	this->type = type;
+}
+
+ShaderProgram::~ShaderProgram() {
+
+}
+
+ProgramParam ShaderProgram::addParam(const String& name, const String& typeString, const String& valueString, bool isAuto, int autoID, int paramType, void *defaultData, void *minData, void *maxData) {
+	ProgramParam newParam;
+	newParam.name = name;
+	newParam.typeString = typeString;
+	newParam.valueString = valueString;	
+	newParam.paramType = paramType;
+	newParam.defaultData = defaultData;
+	newParam.minValue = minData;
+	newParam.maxValue = maxData;
+	newParam.isAuto = isAuto;
+	newParam.autoID = autoID;
+
+	params.push_back(newParam);
+	return newParam;
+}
+
+void ProgramParam::createParamData(int *retType, const String& type, const String& value, const String& min, const String& max, void **valueRes, void **minRes, void **maxRes) {
+		
+		(*valueRes) = NULL;
+		(*minRes) = NULL;
+		(*maxRes) = NULL;
+						
+		if(type == "Number") {
+			*retType = ProgramParam::PARAM_Number;
+			Number *val = new Number();
+			*val = atof(value.c_str());
+			(*valueRes) = (void*)val;
+			
+			val = new Number();
+			*val = atof(min.c_str());
+			(*minRes) = (void*)val;
+
+			val = new Number();
+			*val = atof(max.c_str());
+			(*maxRes) = (void*)val;			
+			
+			return;		
+		} else if(type == "Vector2") {
+			*retType = ProgramParam::PARAM_Vector2;
+			Vector2 *val = new Vector2();
+			(*valueRes) = (void*)val;
+			std::vector<String> values = value.split(" ");
+			if(values.size() == 2) {
+				val->set(atof(values[0].c_str()), atof(values[1].c_str()));
+			} else {
+				printf("Error: A Vector2 must have 2 values (%d provided)!\n", values.size());
+			}
+			return;				
+		} else if(type == "Vector3") {
+			*retType = ProgramParam::PARAM_Vector3;
+			Vector3 *val = new Vector3();
+			(*valueRes) = (void*)val;
+			std::vector<String> values = value.split(" ");
+			if(values.size() == 3) {
+				val->set(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str()));
+			} else {
+				printf("Error: A Vector3 must have 3 values (%d provided)!\n", values.size());
+			}
+			return;
+		} else if(type == "Color") {
+			*retType = ProgramParam::PARAM_Color;
+			Color *val = new Color();
+			(*valueRes) = (void*)val;
+			std::vector<String> values = value.split(" ");
+			if(values.size() == 4) {
+				val->setColor(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str()), atof(values[3].c_str()));
+			} else {
+				printf("Error: A Color must have 4 values (%d provided)!\n", values.size());
+			}
+			return;			
+		} else {
+			*retType = ProgramParam::PARAM_UNKNOWN;
+			(*valueRes) =  NULL;
+		}
+}
+
+
 ShaderBinding::ShaderBinding(Shader *shader) {
 	this->shader = shader;
 }
@@ -108,6 +193,8 @@ Shader::Shader(int type) : Resource(Resource::RESOURCE_SHADER) {
 	numSpotLights = 0;
 	numAreaLights = 0;
 	this->type = type;
+	vp = NULL;
+	fp = NULL;
 }
 
 Shader::~Shader() {

+ 46 - 4
IDE/Contents/Include/PolycodeMaterialEditor.h

@@ -34,8 +34,10 @@ class MaterialBrowserData  {
 public:
 	MaterialBrowserData() {
 		material = NULL;
+		shader = NULL;
 	}
 	Material *material;
+	Shader *shader;
 	String name;
 };
 
@@ -48,10 +50,13 @@ class MaterialBrowser : public UIElement {
 		void Resize(Number width, Number height);
 		
 		UITree * addMaterial(Material *material);
+		UITree * addShader(Shader *shader);
+				
 		void handleEvent(Event *event);
 		
 		MaterialBrowserData *selectedData;
-				
+
+		UIImageButton *newShaderButton;				
 		UIImageButton *newMaterialButton;
 		
 		UITree *selectedNode;
@@ -66,6 +71,40 @@ class MaterialBrowser : public UIElement {
 		UITreeContainer *treeContainer;	
 };
 
+class ShaderEditorPane : public UIElement {
+	public:
+		ShaderEditorPane();
+		~ShaderEditorPane();
+		void Resize(Number width, Number height);
+		void setShader(Shader *shader);
+		
+		void handleEvent(Event *event);
+		
+		void reloadPrograms();
+
+		Shader *currentShader;
+		PolycodeProject *parentProject;
+			
+	protected:
+	
+		
+		bool changingShader;
+
+		bool choosingVertexProgram;
+	
+		PropList *propList;
+		ScreenShape *headerBg;
+		
+		ComboProp *vertexProgramProp;
+		ComboProp *fragmentProgramProp;
+		
+		StringProp *nameProp;
+		BoolProp *screenShaderProp;
+		
+		
+		NumberProp *areaLightsProp;
+		NumberProp *spotLightsProp;		
+};
 
 class MaterialEditorPane : public UIElement {
 	public:
@@ -76,7 +115,7 @@ class MaterialEditorPane : public UIElement {
 		void handleEvent(Event *event);
 		
 		void reloadShaders();
-		void Resize(Number width, Number height);		
+		void Resize(Number width, Number height);	
 		void showPrimitive(unsigned int index);
 		
 		Material *currentMaterial;			
@@ -116,7 +155,9 @@ class MaterialMainWindow : public UIElement {
 	
 	void Resize(Number width, Number height);
 	
-	MaterialEditorPane *materialPane;	
+	MaterialEditorPane *materialPane;
+	ShaderEditorPane *shaderPane;	
+	
 	UIColorPicker *colorPicker;
 };
 
@@ -142,7 +183,8 @@ class PolycodeMaterialEditor : public PolycodeEditor {
 		
 		MaterialMainWindow *mainWindow;
 		std::vector<Material*> materials;
-		
+		std::vector<Shader*> shaders;
+				
 		UITree *selectedMaterialNode;
 };
 

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


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


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


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


BIN
IDE/Contents/Resources/ProjectTemplates/Basic/2D Project/Resources/MyScreen.entity2d


+ 9 - 2
IDE/Contents/Resources/ProjectTemplates/Basic/2D Project/Scripts/Main.lua

@@ -1,4 +1,11 @@
 screen = Screen()
+screen:setNormalizedCoordinates(true, 600)
 
-image = ScreenImage("Resources/polycode_logo.png")
-screen:addChild(image)
+instance = ScreenEntityInstance("Resources/MyScreen.entity2d")
+screen:addChild(instance)
+
+logo = instance:getScreenEntityById("logo", true)
+
+function Update(elapsed)
+	logo:setRotation(logo:getRotation() + (elapsed * 100.0))
+end

+ 7 - 7
IDE/Contents/Resources/ProjectTemplates/Basic/2D Project/template.polyproject

@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<PolycodeProject defaultWidth="640" defaultHeight="480" antiAliasingLevel="0">
-	<backgroundColor red="0.25" green="0.25" blue="0.25" />
-	<entryPoint>Scripts/Main.lua</entryPoint>
-	<packedItems>
-		<item path="Resources" type="folder"/>
-	</packedItems>        	
+<?xml version="1.0" ?>
+<PolycodeProject defaultWidth="640" defaultHeight="480" antiAliasingLevel="0" entryPoint="Scripts/Main.lua" textureFiltering="linear" vSync="false" anisotropyLevel="0" frameRate="60">
+    <backgroundColor red="0.25" green="0.25" blue="0.25" />
+    <polyarray:packedItems>
+        <item type="folder" path="Resources" />
+        <item type="folder" path="Scripts" />
+    </polyarray:packedItems>
 </PolycodeProject>

+ 3 - 0
IDE/Contents/Source/NewFileWindow.cpp

@@ -100,6 +100,8 @@ void NewFileWindow::resetForm() {
 }
 
 void NewFileWindow::handleEvent(Event *event) {
+
+	if(enabled) {
 	if(event->getEventType() == "UIEvent") {
 		if(event->getEventCode() == UIEvent::CLICK_EVENT) {
 			if(event->getDispatcher() == okButton) {
@@ -111,6 +113,7 @@ void NewFileWindow::handleEvent(Event *event) {
 			}									
 		}
 	}
+	}
 	
 	if(event->getEventType() == "UITreeEvent" && event->getEventCode() == UITreeEvent::SELECTED_EVENT) {
 		if(event->getDispatcher() == templateContainer->getRootNode()) {

+ 4 - 0
IDE/Contents/Source/NewProjectWindow.cpp

@@ -131,6 +131,8 @@ void NewProjectWindow::handleEvent(Event *event) {
 				projectLocationInput->setText(pathName);
 
 		}
+		
+		if(enabled) {						
 
 		if(event->getEventCode() == UIEvent::CLICK_EVENT) {
 			if(event->getDispatcher() == okButton) {
@@ -154,6 +156,8 @@ void NewProjectWindow::handleEvent(Event *event) {
 			}			
 			
 		}
+		
+		}
 	}
 	
 	if(event->getEventType() == "UITreeEvent" && event->getEventCode() == UITreeEvent::SELECTED_EVENT) {

+ 250 - 5
IDE/Contents/Source/PolycodeMaterialEditor.cpp

@@ -21,9 +21,215 @@
  */
  
 #include "PolycodeMaterialEditor.h"
+#include "PolycodeFrame.h"
 
 extern UIColorPicker *globalColorPicker;
 extern UIGlobalMenu *globalMenu;
+extern PolycodeFrame *globalFrame;
+
+ShaderEditorPane::ShaderEditorPane() : UIElement() {	
+
+	changingShader = false;
+	currentShader = NULL;
+
+	headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
+	addChild(headerBg);
+	headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+	headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));	
+	
+	propList = new PropList("SHADER EDITOR");
+	addChild(propList);
+	propList->setPosition(0, 0);
+	
+	PropSheet *baseProps = new PropSheet("SHADER SETTINGS", "");
+	propList->addPropSheet(baseProps);
+	
+	nameProp = new StringProp("Name");
+	baseProps->addProp(nameProp);	
+	nameProp->addEventListener(this, Event::CHANGE_EVENT);	
+	
+	screenShaderProp = new BoolProp("Screen shader");
+	baseProps->addProp(screenShaderProp);	
+	screenShaderProp->addEventListener(this, Event::CHANGE_EVENT);	
+	
+	
+	vertexProgramProp = new ComboProp("Vertex prog.");
+	baseProps->addProp(vertexProgramProp);	
+	vertexProgramProp->addEventListener(this, Event::CHANGE_EVENT);	
+
+	fragmentProgramProp = new ComboProp("Fragment prog.");
+	baseProps->addProp(fragmentProgramProp);	
+	fragmentProgramProp->addEventListener(this, Event::CHANGE_EVENT);	
+	
+	areaLightsProp = new NumberProp("Num area lights");
+	baseProps->addProp(areaLightsProp);	
+	areaLightsProp->addEventListener(this, Event::CHANGE_EVENT);
+
+	spotLightsProp = new NumberProp("Num spotlights");
+	baseProps->addProp(spotLightsProp);	
+	spotLightsProp->addEventListener(this, Event::CHANGE_EVENT);
+
+	baseProps->propHeight = 220;
+	
+	PropSheet *vertexProps = new PropSheet("VERTEX PROGRAM OPTIONS", "");
+	propList->addPropSheet(vertexProps);
+
+	PropSheet *fragmentProps = new PropSheet("FRAGMENT PROGRAM OPTIONS", "");
+	propList->addPropSheet(fragmentProps);
+
+
+	propList->updateProps();
+	
+	enabled = false;
+}
+
+ShaderEditorPane::~ShaderEditorPane() {
+
+}
+
+void ShaderEditorPane::handleEvent(Event *event) {
+	if(!changingShader) {
+	
+		if(event->getDispatcher() == nameProp) {
+			currentShader->setName(nameProp->get());
+			dispatchEvent(new Event(), Event::CHANGE_EVENT);			
+		}
+	
+		if(event->getDispatcher() == screenShaderProp) {
+			currentShader->screenShader = screenShaderProp->get();
+			dispatchEvent(new Event(), Event::CHANGE_EVENT);			
+		}
+				
+		if(event->getDispatcher() == areaLightsProp) {
+			currentShader->numAreaLights = floor(areaLightsProp->get());
+			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		}
+
+		if(event->getDispatcher() == spotLightsProp) {
+			currentShader->numSpotLights = floor(spotLightsProp->get());
+			dispatchEvent(new Event(), Event::CHANGE_EVENT);
+		}		
+		
+		if(event->getDispatcher() == vertexProgramProp) {
+			ShaderProgram* vpProgram = (ShaderProgram*)vertexProgramProp->comboEntry->getSelectedItem()->data;
+			if(vpProgram) {			
+				currentShader->setVertexProgram(vpProgram);
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			} else {
+				globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
+				std::vector<String> extensions;
+				extensions.push_back("vert");
+				choosingVertexProgram = true;
+				globalFrame->showAssetBrowser(extensions);				
+			}
+		}		
+
+		if(event->getDispatcher() == fragmentProgramProp) {
+			ShaderProgram* fpProgram = (ShaderProgram*)fragmentProgramProp->comboEntry->getSelectedItem()->data;
+			if(fpProgram) {			
+				currentShader->setFragmentProgram(fpProgram);
+				dispatchEvent(new Event(), Event::CHANGE_EVENT);
+			} else {
+				globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
+				std::vector<String> extensions;
+				extensions.push_back("frag");
+				choosingVertexProgram = false;
+				globalFrame->showAssetBrowser(extensions);			
+			}
+		}
+	}
+	
+	if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
+		String newFontPath = globalFrame->assetBrowser->getSelectedAssetPath();
+		newFontPath = newFontPath.replace(parentProject->getRootFolder()+"/", "");		
+		globalFrame->assetBrowser->removeAllHandlersForListener(this);
+		
+
+		OSFileEntry entry(newFontPath, OSFileEntry::TYPE_FILE);
+		ShaderProgram *newProgram = CoreServices::getInstance()->getMaterialManager()->createProgramFromFile(newFontPath);
+		if(newProgram) {
+			newProgram->setResourceName(entry.name);
+			newProgram->setResourcePath(newFontPath);
+			CoreServices::getInstance()->getResourceManager()->addResource(newProgram);
+		}
+
+		if(choosingVertexProgram) {
+			currentShader->setVertexProgram(newProgram);			
+		} else {
+			currentShader->setFragmentProgram(newProgram);		
+		}
+		
+		dispatchEvent(new Event(), Event::CHANGE_EVENT);		
+		globalFrame->hideModal();
+		
+		reloadPrograms();
+	}	
+}
+
+void ShaderEditorPane::reloadPrograms() {
+	vertexProgramProp->comboEntry->clearItems();
+	fragmentProgramProp->comboEntry->clearItems();
+		
+	vertexProgramProp->comboEntry->addComboItem("Custom...", NULL);
+	fragmentProgramProp->comboEntry->addComboItem("Custom...", NULL);	
+		
+	std::vector<Resource*> programs = CoreServices::getInstance()->getResourceManager()->getResources(Resource::RESOURCE_PROGRAM);
+	
+	for(int i=0; i < programs.size(); i++) {
+		ShaderProgram* program = (ShaderProgram*) programs[i];
+		if(program->type == ShaderProgram::TYPE_VERT) {
+			vertexProgramProp->comboEntry->addComboItem(program->getResourceName(), (void*)program);
+			if(program == currentShader->vp) {
+				vertexProgramProp->comboEntry->setSelectedIndex(vertexProgramProp->comboEntry->getNumItems()-1);
+			}
+		} else if(program->type == ShaderProgram::TYPE_FRAG) {
+			fragmentProgramProp->comboEntry->addComboItem(program->getResourceName(), (void*)program);		
+			if(program == currentShader->fp) {
+				fragmentProgramProp->comboEntry->setSelectedIndex(fragmentProgramProp->comboEntry->getNumItems()-1);
+			}			
+		}
+	}	
+}
+
+void ShaderEditorPane::setShader(Shader *shader) {
+	changingShader = true;
+	
+	currentShader = shader;
+	
+	reloadPrograms();
+		
+	nameProp->set(shader->getName());
+	
+	for(int i=0; i < vertexProgramProp->comboEntry->getNumItems(); i++) {
+		ShaderProgram* program = (ShaderProgram*) vertexProgramProp->comboEntry->getItemAtIndex(i)->data;
+		if(program == shader->vp) {
+			vertexProgramProp->comboEntry->setSelectedIndex(i);
+		}
+	}
+
+	for(int i=0; i < fragmentProgramProp->comboEntry->getNumItems(); i++) {
+		ShaderProgram* program = (ShaderProgram*) fragmentProgramProp->comboEntry->getItemAtIndex(i)->data;
+		if(program == shader->fp) {
+			fragmentProgramProp->comboEntry->setSelectedIndex(i);
+		}
+	}
+	
+	screenShaderProp->set(shader->screenShader);
+	
+	areaLightsProp->set(shader->numAreaLights);
+	spotLightsProp->set(shader->numSpotLights);
+	
+	enabled = true;
+	
+	changingShader = false;	
+}
+
+void ShaderEditorPane::Resize(Number width, Number height) {
+	headerBg->setShapeSize(width, 30);	
+	propList->Resize(370, height);
+	propList->updateProps();
+}
+
 
 MaterialEditorPane::MaterialEditorPane() : UIElement() {	
 
@@ -251,6 +457,8 @@ void MaterialEditorPane::setMaterial(Material *material) {
 	currentMaterial = material;
 	previewPrimitive->setMaterial(material);		
 	
+	reloadShaders();
+	
 	if(!currentMaterial)
 		return;
 	
@@ -284,7 +492,10 @@ MaterialEditorPane::~MaterialEditorPane() {
 MaterialMainWindow::MaterialMainWindow() : UIElement() {
 
 	materialPane = new MaterialEditorPane();
+	shaderPane = new ShaderEditorPane();
+		
 	addChild(materialPane);
+	addChild(shaderPane);	
 	enableScissor = true;
 }
 	
@@ -292,6 +503,7 @@ void MaterialMainWindow::Resize(Number width, Number height) {
 	Vector2 pos = getScreenPosition();	
 	scissorBox.setRect(pos.x,pos.y,width, height);
 	materialPane->Resize(width, height);
+	shaderPane->Resize(width, height);
 }
 
 MaterialBrowser::MaterialBrowser() : UIElement() {
@@ -300,8 +512,8 @@ MaterialBrowser::MaterialBrowser() : UIElement() {
 	treeContainer->getRootNode()->addEventListener(this, UITreeEvent::SELECTED_EVENT);
 	treeContainer->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 		
-	shadersNode = treeContainer->getRootNode()->addTreeChild("folder.png", "Shaders", NULL);
-	materialsNode = treeContainer->getRootNode()->addTreeChild("folder.png", "Materials", NULL);
+	shadersNode = treeContainer->getRootNode()->addTreeChild("Images/shader_icon.png", "Shaders", NULL);
+	materialsNode = treeContainer->getRootNode()->addTreeChild("Images/material_icon.png", "Materials", NULL);
 	cubemapsNode = treeContainer->getRootNode()->addTreeChild("folder.png", "Cubemaps", NULL);
 	cubemapsNode = treeContainer->getRootNode()->addTreeChild("folder.png", "Post Effects", NULL);
 				
@@ -313,10 +525,13 @@ MaterialBrowser::MaterialBrowser() : UIElement() {
 	headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
 	headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));	
 
+	newShaderButton = new UIImageButton("Images/new_shader.png");
+	addChild(newShaderButton);
+	newShaderButton->setPosition(5,4);
 	
 	newMaterialButton = new UIImageButton("Images/new_material.png");
 	addChild(newMaterialButton);
-	newMaterialButton->setPosition(5,5);
+	newMaterialButton->setPosition(28,4);
 	
 	selectedNode = NULL;
 
@@ -344,6 +559,13 @@ UITree *MaterialBrowser::addMaterial(Material *material) {
 	return materialsNode->addTreeChild("material_icon.png", material->getName(), (void*)data);
 }
 
+UITree *MaterialBrowser::addShader(Shader *shader) {
+	MaterialBrowserData *data = new MaterialBrowserData();
+	data->shader = shader;
+	return shadersNode->addTreeChild("shader_icon.png", shader->getName(), (void*)data);
+}
+
+
 MaterialBrowser::~MaterialBrowser() {
 
 }
@@ -373,8 +595,14 @@ bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
 	
 	materialBrowser->addEventListener(this, Event::CHANGE_EVENT);
 	
-	materials = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(filePath.fullPath);
 	
+	shaders = CoreServices::getInstance()->getMaterialManager()->loadShadersFromFile(filePath.fullPath);
+	for(int i=0; i < shaders.size(); i++) {
+		materialBrowser->addShader(shaders[i]);
+		CoreServices::getInstance()->getMaterialManager()->addShader(shaders[i]);
+	}	
+	
+	materials = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(filePath.fullPath);	
 	for(int i=0; i < materials.size(); i++) {
 		materialBrowser->addMaterial(materials[i]);
 	}
@@ -383,6 +611,9 @@ bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
 	mainSizer->addLeftChild(mainWindow);
 	
 	mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
+	mainWindow->shaderPane->addEventListener(this, Event::CHANGE_EVENT);
+	
+	mainWindow->shaderPane->parentProject = parentProject;
 	
 	materialBrowser->newMaterialButton->addEventListener(this, UIEvent::CLICK_EVENT);
 	
@@ -493,6 +724,14 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 		}
 		setHasChanges(true);
 	}
+
+	if(event->getDispatcher() == mainWindow->shaderPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
+		if(selectedMaterialNode && mainWindow->shaderPane->currentShader) {
+			selectedMaterialNode->setLabelText(mainWindow->shaderPane->currentShader->getName());
+		}
+		setHasChanges(true);
+	}
+
 		
 	if(event->getDispatcher() == materialBrowser->newMaterialButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
 		Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("Untitled", "DefaultShader");
@@ -505,9 +744,15 @@ void PolycodeMaterialEditor::handleEvent(Event *event) {
 	if(event->getDispatcher() == materialBrowser) {
 		if(event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
 			if(materialBrowser->selectedData)  {
+				mainWindow->materialPane->enabled = false;
+				mainWindow->shaderPane->enabled = false;
+								
 				if(materialBrowser->selectedData->material) {
 					selectedMaterialNode = materialBrowser->selectedNode;				
-					mainWindow->materialPane->setMaterial(materialBrowser->selectedData->material);
+					mainWindow->materialPane->setMaterial(materialBrowser->selectedData->material);					
+				} else if(materialBrowser->selectedData->shader) {
+					selectedMaterialNode = materialBrowser->selectedNode;				
+					mainWindow->shaderPane->setShader(materialBrowser->selectedData->shader);
 				}
 			}			
 		}

+ 2 - 2
IDE/Contents/Source/PolycodeToolLauncher.cpp

@@ -91,9 +91,9 @@ void PolycodeToolLauncher::buildProject(PolycodeProject *project, String destina
 #else
 	String command = polycodeBasePath+"/Standalone/Bin/polybuild";
 	String inFolder = projectBasePath; 
-	String args = "--config="+projectPath+" --out="+destinationPath;
+	String args = "--config=\""+projectPath+"\" --out="+destinationPath;
 	String ret = CoreServices::getInstance()->getCore()->executeExternalCommand(command, args, inFolder);
-//	PolycodeConsole::print(ret);
+	PolycodeConsole::print(ret);
 #endif
 
 }