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; }