示例#1
0
LocalShaderParam *LocalShaderParam::Copy() {
    LocalShaderParam *copyParam = new LocalShaderParam();
    copyParam->name = name;
    copyParam->type = type;
    copyParam->data = ProgramParam::createParamData(type);
    copyParam->ownsPointer = ownsPointer;
    
    switch(type) {
        case ProgramParam::PARAM_NUMBER:
        {
            copyParam->setNumber(getNumber());
        }
        break;
        case ProgramParam::PARAM_VECTOR2:
        {
            copyParam->setVector2(getVector2());
        }
        break;
        case ProgramParam::PARAM_VECTOR3:
        {
            copyParam->setVector3(getVector3());
        }
        break;
        case ProgramParam::PARAM_COLOR:
        {
            copyParam->setColor(getColor());
        }
        break;
        case ProgramParam::PARAM_MATRIX:
        {
            copyParam->setMatrix4(getMatrix4());
        }
        break;
    }
    return copyParam;
}
Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
	TiXmlElement *nodeElement = node->ToElement();
	if (!nodeElement) return NULL; // Skip comment nodes

	String mname = nodeElement->Attribute("name");
	TiXmlNode* pChild, *pChild2,*pChild3;
	Shader *materialShader;
	ShaderBinding *newShaderBinding;
	
	vector<Shader*> materialShaders;
	vector<ShaderBinding*> newShaderBindings;
	vector<ShaderRenderTarget*> renderTargets;	

	Material *newMaterial = new Material(mname);
	
	
	if(nodeElement->Attribute("blendingMode")) {
		newMaterial->blendingMode = atoi(nodeElement->Attribute("blendingMode"));
	}

	for (pChild3 = node->FirstChild(); pChild3 != 0; pChild3 = pChild3->NextSibling()) {
		TiXmlElement *pChild3Element = pChild3->ToElement();
		if (!pChild3Element) continue; // Skip comment nodes

		if(strcmp(pChild3->Value(), "rendertargets") == 0) {
			
			if(pChild3Element->Attribute("type")) {
				if(strcmp(pChild3Element->Attribute("type"), "rgba_fp16") == 0) {
					newMaterial->fp16RenderTargets = true;
				}			
			}
		
			for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
				TiXmlElement *pChildElement = pChild->ToElement();
				if (!pChildElement) continue; // Skip comment nodes

				if(strcmp(pChild->Value(), "rendertarget") == 0) {
					ShaderRenderTarget *newTarget = new ShaderRenderTarget;
					newTarget->id = pChildElement->Attribute("id");
					newTarget->width = CoreServices::getInstance()->getRenderer()->getXRes();
					newTarget->height = CoreServices::getInstance()->getRenderer()->getYRes();
					newTarget->sizeMode = ShaderRenderTarget::SIZE_MODE_PIXELS;					
					if(pChildElement->Attribute("width") && pChildElement->Attribute("height")) {
						newTarget->width = atof(pChildElement->Attribute("width"));
						newTarget->height = atof(pChildElement->Attribute("height"));	
						if(pChildElement->Attribute("sizeMode")) {
							if(strcmp(pChildElement->Attribute("sizeMode"), "normalized") == 0) {
								if(newTarget->width > 1.0f)
									newTarget->width = 1.0f;
								if(newTarget->height > 1.0f)
									newTarget->height = 1.0f;
									
								newTarget->width = ((Number)CoreServices::getInstance()->getRenderer()->getXRes()) * newTarget->width;
								newTarget->height = ((Number)CoreServices::getInstance()->getRenderer()->getYRes()) * newTarget->height;
							}						
						}
					}						
//					Texture *newTexture = CoreServices::getInstance()->getMaterialManager()->createNewTexture(newTarget->width, newTarget->height, true);
					Texture *newTexture, *temp;
					CoreServices::getInstance()->getRenderer()->createRenderTextures(&newTexture, &temp, (int)newTarget->width, (int)newTarget->height, newMaterial->fp16RenderTargets);
					newTexture->setResourceName(newTarget->id);
					//CoreServices::getInstance()->getResourceManager()->addResource(newTexture);
					newTarget->texture = newTexture;
					renderTargets.push_back(newTarget);

				}
			}
		}	
	}
	
	for (pChild3 = node->FirstChild(); pChild3 != 0; pChild3 = pChild3->NextSibling()) {
		TiXmlElement *pChild3Element = pChild3->ToElement();
		if (!pChild3Element) continue; // Skip comment nodes
		
		if(strcmp(pChild3->Value(), "shader") == 0) {
			materialShader = setShaderFromXMLNode(pChild3);
			if(materialShader) {
				newShaderBinding = materialShader->createBinding();
				materialShaders.push_back(materialShader);
				newShaderBindings.push_back(newShaderBinding);
				for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
					TiXmlElement *pChildElement = pChild->ToElement();
					if (!pChildElement) continue; // Skip comment nodes

					if(strcmp(pChild->Value(), "params") == 0) {
						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
							TiXmlElement *pChild2Element = pChild2->ToElement();
							if (!pChild2Element) continue; // Skip comment nodes

							if(strcmp(pChild2->Value(), "param") == 0){
								String pname =  pChild2Element->Attribute("name");
								
								if(!CoreServices::getInstance()->getRenderer()->getDataPointerForName(pname)) {								
								String pvalue =  pChild2Element->Attribute("value");																
								int type = materialShader->getExpectedParamType(pname);								
								LocalShaderParam *param = newShaderBinding->addParam(type, pname);
								
								
								if(param) {
									switch(type) {
										case ProgramParam::PARAM_NUMBER:
										{
											param->setNumber(atof(pvalue.c_str()));
										}
										break;
										case ProgramParam::PARAM_VECTOR2:
										{
											std::vector<String> values = pvalue.split(" ");
											if(values.size() == 2) {
												param->setVector2(Vector2(atof(values[0].c_str()), atof(values[1].c_str())));
											} else {
												printf("Material parameter error: A Vector2 must have 2 values (%d provided)!\n", (int)values.size());
											}
										}											
										break;
										case ProgramParam::PARAM_VECTOR3:
										{
											std::vector<String> values = pvalue.split(" ");
											if(values.size() == 3) {
												param->setVector3(Vector3(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str())));
											} else {
												printf("Material parameter error: A Vector3 must have 3 values (%d provided)!\n", (int)values.size());
											}
										}										
										break;
										case ProgramParam::PARAM_COLOR:
										{
											std::vector<String> values = pvalue.split(" ");
											if(values.size() == 4) {
												param->setColor(Color(atof(values[0].c_str()), atof(values[1].c_str()), atof(values[2].c_str()), atof(values[3].c_str())));
											} else {
												printf("Material parameter error: A Vector3 must have 3 values (%d provided)!\n", (int)values.size());
											}
										}										
										break;										
									}
									}
								}
							}						
						}
					}
					if(strcmp(pChild->Value(), "targettextures") == 0) {
						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
							TiXmlElement *pChild2Element = pChild2->ToElement();
							if (!pChild2Element) continue; // Skip comment nodes

							if(strcmp(pChild2->Value(), "targettexture") == 0){
							
								RenderTargetBinding* newBinding = new RenderTargetBinding;
								newBinding->id = pChild2Element->Attribute("id");
								
								newBinding->name = "";
								if(pChild2Element->Attribute("name")) {
									newBinding->name = pChild2Element->Attribute("name");
								}
								String mode = pChild2Element->Attribute("mode");
								if(strcmp(mode.c_str(), "in") == 0) {
									newBinding->mode = RenderTargetBinding::MODE_IN;
								} else {
									newBinding->mode = RenderTargetBinding::MODE_OUT;								
								}
																
								newShaderBinding->addRenderTargetBinding(newBinding);
								//Texture *texture =  (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, newBinding->id);
//								newBinding->texture = texture;
								
								for(int l=0; l < renderTargets.size(); l++) {
									if(renderTargets[l]->id == newBinding->id) {
										printf("Assigning texture to %s\n", newBinding->id.c_str());
										newBinding->texture = renderTargets[l]->texture;
										newBinding->width = renderTargets[l]->width;
										newBinding->height = renderTargets[l]->height;
									}
								}
								
								if(newBinding->mode == RenderTargetBinding::MODE_IN) {
									newShaderBinding->addTexture(newBinding->name, newBinding->texture);
								}
							}						
						}
					}					
					if(strcmp(pChild->Value(), "textures") == 0) {
						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
							TiXmlElement *pChild2Element = pChild2->ToElement();
							if (!pChild2Element) continue; // Skip comment nodes

							if(strcmp(pChild2->Value(), "texture") == 0){
								String tname = "";
								if(pChild2Element->Attribute("name")) {
									tname =  pChild2Element->Attribute("name");
								}
								Texture *texture = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(pChild2Element->GetText());
								newShaderBinding->addTexture(tname,texture);
//								newShaderBinding->addTexture(tname, (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, pChild2Element->GetText()));
							}
							
							if(strcmp(pChild2->Value(), "cubemap") == 0){
								String tname = "";
								if(pChild2Element->Attribute("name")) {
									tname =  pChild2Element->Attribute("name");
								}
								newShaderBinding->addCubemap(tname, (Cubemap*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_CUBEMAP, pChild2Element->GetText()));
							}
							
						}
					}
				}
			}
		}
	}
	

	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]);
	}
	
	return newMaterial;
}