| 
					
				 | 
			
			
				@@ -319,11 +319,12 @@ void tnsShaderApplyShadowMatrix(tnsShader *tns, tnsMatrix44d m){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glUniformMatrix4fv(tns->iShadow, 1, 0, mf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-char* tnsEnsureShaderCommoms(char* Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+char* tnsEnsureShaderCommoms(char* Content, char* Material){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char* c=0,*c1=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     c1=strSub(Content,"#with TNS_SHADER_COLOR_COMMON",TNS_SHADER_COLOR_COMMON); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     c=strSub(c1,"#with LA_SHADER_LIB_FXAA",LA_SHADER_LIB_FXAA); free(c1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c1=strSub(c,"#with TNS_SHADER_MATERIAL",Material?Material:""); free(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return c1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int tnsNewVertexShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int status = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -335,7 +336,7 @@ int tnsNewVertexShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     VertexShaderObject = glCreateShader(GL_VERTEX_SHADER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    char* UseContent=tnsEnsureShaderCommoms(Content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char* UseContent=tnsEnsureShaderCommoms(Content,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glShaderSource(VertexShaderObject, 1, &UseContent, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glCompileShader(VertexShaderObject); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glGetShaderiv(VertexShaderObject, GL_COMPILE_STATUS, &status); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -349,7 +350,7 @@ int tnsNewVertexShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return VertexShaderObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-int tnsNewFragmentShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int tnsNewFragmentShaderMaterial(char *Content, char* Material){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int status = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char error[1024]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GLuint FragmentShaderObject; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -359,7 +360,7 @@ int tnsNewFragmentShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     FragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    char* UseContent=tnsEnsureShaderCommoms(Content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char* UseContent=tnsEnsureShaderCommoms(Content,Material); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glShaderSource(FragmentShaderObject, 1, &UseContent, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glCompileShader(FragmentShaderObject); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glGetShaderiv(FragmentShaderObject, GL_COMPILE_STATUS, &status); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -373,6 +374,9 @@ int tnsNewFragmentShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return FragmentShaderObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int tnsNewFragmentShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return tnsNewFragmentShaderMaterial(Content,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int tnsNewGeometryShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int status = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     char error[1024]; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -383,7 +387,7 @@ int tnsNewGeometryShader(char *Content){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GeometryShaderObject = glCreateShader(GL_GEOMETRY_SHADER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    char* UseContent=tnsEnsureShaderCommoms(Content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char* UseContent=tnsEnsureShaderCommoms(Content,0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glShaderSource(GeometryShaderObject, 1, &UseContent, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glCompileShader(GeometryShaderObject); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     glGetShaderiv(GeometryShaderObject, GL_COMPILE_STATUS, &status); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -455,28 +459,25 @@ int tnsEnableShader(int index){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int tnsEnableShaderv(tnsShader *shader){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tnsMatrixStackItem *tmsi; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tnsShader *tns = shader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!tns){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        glUseProgram(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        T->CurrentShader = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        T->BindedShader = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    glUseProgram(tns->glProgramID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    T->CurrentShader = tns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    T->BindedShader = tns; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tnsShader *s = shader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!s){ glUseProgram(0); T->CurrentShader = 0;T->BindedShader = 0; return 0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glUseProgram(s->glProgramID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    T->CurrentShader = s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    T->BindedShader = s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tmsi = tKnlGetCurrentMatStackItem(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tnsShaderApplyProjection(tns, tmsi->projection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tnsShaderApplyProjectionInverse(tns, tmsi->projection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tnsShaderApplyView(tns, tmsi->view); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    tnsShaderApplyModel(tns, tmsi->model); tnsUseShader(tns); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //if (tns->iVertex != -1) glEnableVertexAttribArray(tns->iVertex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //if (tns->iColor != -1) glEnableVertexAttribArray(tns->iColor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //if (tns->iNormal != -1) glEnableVertexAttribArray(tns->iNormal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //if (tns->iUV != -1) glEnableVertexAttribArray(tns->iUV); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tnsShaderApplyProjection(s, tmsi->projection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tnsShaderApplyProjectionInverse(s, tmsi->projection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tnsShaderApplyView(s, tmsi->view); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tnsShaderApplyModel(s, tmsi->model); tnsUseShader(s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(s->iUseNormal) glUniform1i(s->iUseNormal,T->SetUseNormal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(s->uViewPos) glUniform3fv(s->uViewPos,1,T->SetViewPos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(s->iUseHalftone) glUniform1f(s->iUseHalftone,T->SetUseHalftone); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(s->iHalftoneSize) glUniform1f(s->iHalftoneSize,T->SetHalftoneSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //if(s->iTextureMode) glUniform1i(s->iTextureMode,T->StateTextureMode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //if(cs->iSampleAmount) glUniform1i(cs->iSampleAmount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int tnsUseShader(tnsShader *shader){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1516,6 +1517,9 @@ void tnsCommandUseUniformColor(tnsBatchCommand*c, real* color){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tnsVectorCopy4d(color, c->UniformColor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     c->UseUniformColor=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void tnsCommandUseMaterial(tnsBatchCommand*c, tnsMaterial* material){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c->Material=material; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void tnsCommandUseWidth(tnsBatchCommand*c, real width){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     c->Width=width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1561,13 +1565,8 @@ void tnsDeleteBatch(tnsBatch *b){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     FreeMem(b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	//int Mode = batch->DrawMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	if (!batch) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void tnsDrawBatchInitArrayStates(tnsBatch* batch){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tnsShader* cs=T->BindedShader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int Drawn=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	//glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	glBindBuffer(GL_ARRAY_BUFFER, batch->VBO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	glEnableVertexAttribArray(cs->iVertex); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1587,12 +1586,25 @@ int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUni 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(cs->iUV>=0){ glDisableVertexAttribArray(cs->iUV); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tnsUniformUseTexture(cs, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (!batch) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int Drawn=0; tnsShader *LastShader=T->BindedShader,*SaveShader=T->BindedShader; int NeedInit=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int IsOverrideColor=0; int PointSizeChanged=0,LineWidthChanged=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	for (tnsBatchCommand* bc = batch->Branches.pFirst; bc; bc = bc->Item.pNext) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(OverrideCommand && !strSame(OverrideCommand, bc->name)){ continue; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(!OverrideCommand && bc->HiddenByDefault){ continue; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(cs->iColor){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(NeedInit || (bc->Material && LastShader!=bc->Material->Shader) || ((!bc->Material)&&LastShader!=SaveShader)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(bc->Material && bc->Material->Shader){ LastShader=bc->Material->Shader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                tnsUseShader(LastShader); tnsEnableShaderv(LastShader); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                tnsUseShader(SaveShader); tnsEnableShaderv(SaveShader); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tnsDrawBatchInitArrayStates(batch); NeedInit=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tnsShader* cs=T->BindedShader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(cs->iColor>-1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if(bc->OverrideColorArray){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 glBindBuffer(GL_ARRAY_BUFFER, bc->CBO); glEnableVertexAttribArray(cs->iColor); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 glVertexAttribPointer(cs->iColor, bc->ColorDimension, GL_FLOAT, 0, 0, 0); IsOverrideColor=1; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1619,6 +1631,8 @@ int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUni 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(PointSizeChanged){ glPointSize(1); } if(LineWidthChanged){ glLineWidth(1); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(SaveShader!=LastShader){ tnsUseShader(SaveShader); tnsEnableShaderv(SaveShader); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return Drawn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -3637,7 +3651,8 @@ void tnsApplyCameraView(int W, int H, tnsCamera *Camera){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (current_shader = T->CurrentShader){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         tnsShaderApplyView(current_shader, result); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(current_shader->uViewPos>-1) glUniform3f(current_shader->uViewPos,LA_COLOR3(Camera->Base.Location)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(current_shader->uViewPos>-1) glUniform3f(current_shader->uViewPos,LA_COLOR3(Camera->Base.GLocation)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tnsVectorSet3v(T->SetViewPos,Camera->Base.GLocation); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void tnsApplyShadowCameraView(tnsLight *Light){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4103,6 +4118,7 @@ tnsMaterial *tnsCreateMaterial(char *Name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tnsMaterial *m; if(!Name || !Name[0]) return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     m = memAcquireHyper(sizeof(tnsMaterial)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     strSafeSet(&m->Name, Name); tnsVectorSet4(m->Color,0.8,0.8,0.8,1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    m->Page=memAcquire(sizeof(laRackPage)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     lstAppendItem(&T->World->Materials, m); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return m; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4112,7 +4128,9 @@ tnsMaterial *tnsFindMaterial(char *name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void tnsRemoveMaterial(tnsMaterial* mat){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    lstRemoveItem(&T->World->Materials,mat); memLeave(mat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lstRemoveItem(&T->World->Materials,mat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laNodeRack* rr; while(rr=lstPopItem(&mat->Page->Racks)){ laDestroyRack(rr); } memLeave(mat->Page); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memLeave(mat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 tnsMaterialSlot* tnsNewMaterialSlot(tnsMeshObject* mo){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(mo->Base.Type!=TNS_OBJECT_MESH) return 0; short nextid=0,found=1; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4122,7 +4140,7 @@ tnsMaterialSlot* tnsNewMaterialSlot(tnsMeshObject* mo){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tnsMaterialSlot* ms=memAcquire(sizeof(tnsMaterialSlot)); lstAppendItem(&mo->Materials,ms); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ms->Index=nextid; ms->Parent=mo; memAssignRef(mo,&mo->CurrentMaterial,ms); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ms->Index=nextid; memAssignRef(ms,&ms->Parent,mo); memAssignRef(mo,&mo->CurrentMaterial,ms); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return ms; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void tnsRemoveMaterialSlot(tnsMeshObject* mo, tnsMaterialSlot* ms){ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -4138,6 +4156,17 @@ void tnsAssignMaterialSlot(tnsMeshObject* mo, tnsMaterialSlot* ms){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void tnsEnsureMaterialShader(tnsMaterial* mat, int Refresh){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(Refresh){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(mat->Shader && mat->Shader!=T->immShader){ tnsDeleteShaderProgram(mat->Shader); mat->Shader=0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!(mat->Page->Script&&mat->Page->Script->Ptr)){ mat->Shader=T->immShader; return; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    char* str=mat->Page->Script->Ptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    mat->Shader = tnsNewShaderProgram( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tnsNewVertexShader(LA_IMM_VERTEX_SHADER),tnsNewFragmentShaderMaterial(LA_OBJECT_FRAGMENT_SHADER,str),-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!mat->Shader){ mat->Shader=T->immShader; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //==================================================================[Util] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define MAX3(a, b, c) \ 
			 |