示例#1
0
void Camera::createPostFilter(Material *shaderMaterial) {
	if(!shaderMaterial)
		return;
	if(shaderMaterial->getNumShaders() == 0)
		return;
		
	this->filterShaderMaterial = shaderMaterial;
	
	// TODO: make it save the textures to resource manager and check if they there
//	originalSceneTexture = CoreServices::getInstance()->getMaterialManager()->createNewTexture(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes());
//	zBufferSceneTexture = CoreServices::getInstance()->getMaterialManager()->createFramebufferTexture(CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes(), 0);

	if(!originalSceneTexture) {
		CoreServices::getInstance()->getRenderer()->createRenderTextures(&originalSceneTexture, &zBufferSceneTexture, CoreServices::getInstance()->getCore()->getXRes(), CoreServices::getInstance()->getCore()->getYRes(), shaderMaterial->fp16RenderTargets);
	}
	
	for(int i=0; i < shaderMaterial->getNumShaders(); i++) {
		ShaderBinding* binding = shaderMaterial->getShader(i)->createBinding();		
		if(i == 0) {
			binding->addTexture("screenColorBuffer", originalSceneTexture);
			binding->addTexture("screenDepthBuffer", zBufferSceneTexture);
		}
		localShaderOptions.push_back(binding);
		binding->addLocalParam("exposure", (void*)&exposureLevel);				
	}
	

	_hasFilterShader = true;
}
示例#2
0
void Screen::drawFilter() {
	
	if(!filterShaderMaterial)
		return;
	
	Renderer *renderer = CoreServices::getInstance()->getRenderer();
	
	renderer->bindFrameBufferTexture(originalSceneTexture);
	
	Render();
	renderer->unbindFramebuffers();
	
	ShaderBinding* materialBinding;		
	for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
		materialBinding = filterShaderMaterial->getShaderBinding(i);
		
		for(int j=0; j < materialBinding->getNumColorTargetBindings(); j++) {
			RenderTargetBinding *colorBinding = materialBinding->getColorTargetBinding(j);
			materialBinding->clearTexture(colorBinding->name);
			materialBinding->addTexture(colorBinding->name, originalSceneTexture);
		}
		
		renderer->applyMaterial(filterShaderMaterial, localShaderOptions[i], i);	
			
		if(i==filterShaderMaterial->getNumShaders()-1) {
			renderer->loadIdentity();
			renderer->drawScreenQuad(renderer->getXRes(), renderer->getYRes());		
		} else {
			for(int j=0; j < materialBinding->getNumOutTargetBindings(); j++) {
				renderer->bindFrameBufferTexture(materialBinding->getOutTargetBinding(j)->texture);
				
				renderer->drawScreenQuad(materialBinding->getOutTargetBinding(j)->width, materialBinding->getOutTargetBinding(j)->height);
				renderer->unbindFramebuffers();
			}						
		}
		renderer->clearShader();
		renderer->loadIdentity();		
		renderer->setOrthoMode();
	}
	
}
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;
}
示例#4
0
void Camera::drawFilter(Texture *targetTexture, Number targetTextureWidth, Number targetTextureHeight, Texture *targetColorTexture, Texture *targetZTexture) {

	if(!filterShaderMaterial)
		return;
		
	Texture *finalTargetColorTexture;
	Texture *finalTargetZTexture;	
		
	if(targetTexture) {	
		finalTargetColorTexture = targetColorTexture;
		finalTargetZTexture = targetZTexture;		
		CoreServices::getInstance()->getRenderer()->setViewportSize(targetTextureWidth, targetTextureHeight);		
	} else {
		finalTargetColorTexture = originalSceneTexture;
		finalTargetZTexture = zBufferSceneTexture;	
		CoreServices::getInstance()->getRenderer()->setViewportSize(CoreServices::getInstance()->getRenderer()->getXRes(), CoreServices::getInstance()->getRenderer()->getYRes());
	}
	CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(finalTargetColorTexture);
	CoreServices::getInstance()->getRenderer()->bindFrameBufferTextureDepth(finalTargetZTexture);
	parentScene->Render(this);
	CoreServices::getInstance()->getRenderer()->unbindFramebuffers();


	ShaderBinding* materialBinding;		
	for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
		materialBinding = filterShaderMaterial->getShaderBinding(i);
		
		for(int j=0; j < materialBinding->getNumColorTargetBindings(); j++) {
			RenderTargetBinding *colorBinding = materialBinding->getColorTargetBinding(j);
			materialBinding->clearTexture(colorBinding->name);
			materialBinding->addTexture(colorBinding->name, finalTargetColorTexture);
		}

		for(int j=0; j < materialBinding->getNumDepthTargetBindings(); j++) {
			RenderTargetBinding *depthBinding = materialBinding->getDepthTargetBinding(j);
			materialBinding->clearTexture(depthBinding->name);
			materialBinding->addTexture(depthBinding->name, finalTargetZTexture);
		}
		
		CoreServices::getInstance()->getRenderer()->applyMaterial(filterShaderMaterial, localShaderOptions[i], i);		
		if(i==filterShaderMaterial->getNumShaders()-1) {
				if(targetTexture) {
					CoreServices::getInstance()->getRenderer()->setViewportSize(targetTextureWidth, targetTextureHeight);	
					CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(targetTexture);								
					CoreServices::getInstance()->getRenderer()->clearScreen();
					CoreServices::getInstance()->getRenderer()->loadIdentity();

					CoreServices::getInstance()->getRenderer()->drawScreenQuad(targetTextureWidth, targetTextureHeight);
					CoreServices::getInstance()->getRenderer()->unbindFramebuffers();									
				} else {
					CoreServices::getInstance()->getRenderer()->setViewportSize(CoreServices::getInstance()->getRenderer()->getXRes(), CoreServices::getInstance()->getRenderer()->getYRes());
					CoreServices::getInstance()->getRenderer()->clearScreen();
					CoreServices::getInstance()->getRenderer()->loadIdentity();
					CoreServices::getInstance()->getRenderer()->drawScreenQuad(CoreServices::getInstance()->getRenderer()->getXRes(), CoreServices::getInstance()->getRenderer()->getYRes());
				}
		} else {
			for(int j=0; j < materialBinding->getNumOutTargetBindings(); j++) {
				Texture *bindingTexture = materialBinding->getOutTargetBinding(j)->texture;
				if(bindingTexture) {
					CoreServices::getInstance()->getRenderer()->setViewportSize(bindingTexture->getWidth(), bindingTexture->getHeight());
					CoreServices::getInstance()->getRenderer()->bindFrameBufferTexture(bindingTexture);				
					CoreServices::getInstance()->getRenderer()->drawScreenQuad(bindingTexture->getWidth(), bindingTexture->getHeight());
					CoreServices::getInstance()->getRenderer()->unbindFramebuffers();
				}
			}		
		}
		CoreServices::getInstance()->getRenderer()->clearShader();
		CoreServices::getInstance()->getRenderer()->loadIdentity();
	}
}
示例#5
0
Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
	String mname = node->ToElement()->Attribute("name");
	TiXmlNode* pChild, *pChild2,*pChild3;
	Shader *materialShader;
	ShaderBinding *newShaderBinding;
	
	vector<Shader*> materialShaders;
	vector<ShaderBinding*> newShaderBindings;
	vector<ShaderRenderTarget*> renderTargets;	

	Material *newMaterial = new Material(mname);

	for (pChild3 = node->FirstChild(); pChild3 != 0; pChild3 = pChild3->NextSibling()) {
		if(strcmp(pChild3->Value(), "rendertargets") == 0) {
			
			if(pChild3->ToElement()->Attribute("type")) {
				if(strcmp(pChild3->ToElement()->Attribute("type"), "rgba_fp16") == 0) {
					newMaterial->fp16RenderTargets = true;
				}			
			}
		
			for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
				if(strcmp(pChild->Value(), "rendertarget") == 0) {
					ShaderRenderTarget *newTarget = new ShaderRenderTarget;
					newTarget->id = pChild->ToElement()->Attribute("id");
					newTarget->width = CoreServices::getInstance()->getRenderer()->getXRes();
					newTarget->height = CoreServices::getInstance()->getRenderer()->getYRes();
					newTarget->sizeMode = ShaderRenderTarget::SIZE_MODE_PIXELS;					
					if(pChild->ToElement()->Attribute("width") && pChild->ToElement()->Attribute("height")) {
						newTarget->width = atof(pChild->ToElement()->Attribute("width"));
						newTarget->height = atof(pChild->ToElement()->Attribute("height"));	
						if(pChild->ToElement()->Attribute("sizeMode")) {
							if(strcmp(pChild->ToElement()->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()) {
	
		if(strcmp(pChild3->Value(), "specularValue") == 0) {
			newMaterial->specularValue = atof(pChild3->ToElement()->GetText());
		}

		if(strcmp(pChild3->Value(), "specularStrength") == 0) {
			newMaterial->specularStrength = atof(pChild3->ToElement()->GetText());
		}


		if(strcmp(pChild3->Value(), "specularColor") == 0) {		
			String value = pChild3->ToElement()->GetText();
			vector<String> values = value.split(" ");
			if(values.size() == 4) {
				newMaterial->specularColor.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: Incorrect number of values for specularColor (%d provided)!\n", values.size());
			}
		}

		if(strcmp(pChild3->Value(), "diffuseColor") == 0) {
			String value = pChild3->ToElement()->GetText();
			vector<String> values = value.split(" ");
			if(values.size() == 4) {
				newMaterial->diffuseColor.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: Incorrect number of values for diffuseColor (%d provided)!\n", values.size());
			}

		}
		
		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()) {
					if(strcmp(pChild->Value(), "params") == 0) {
						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
							if(strcmp(pChild2->Value(), "param") == 0){
								String pname =  pChild2->ToElement()->Attribute("name");
								String ptype =  pChild2->ToElement()->Attribute("type");
								String pvalue =  pChild2->ToElement()->Attribute("value");
								newShaderBinding->addParam(ptype, pname, pvalue);
							}						
						}
					}
					if(strcmp(pChild->Value(), "targettextures") == 0) {
						for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
							if(strcmp(pChild2->Value(), "targettexture") == 0){
							
								RenderTargetBinding* newBinding = new RenderTargetBinding;
								newBinding->id = pChild2->ToElement()->Attribute("id");
								
								newBinding->name = "";
								if(pChild2->ToElement()->Attribute("name")) {
									newBinding->name = pChild2->ToElement()->Attribute("name");
								}
								String mode = pChild2->ToElement()->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()) {
							if(strcmp(pChild2->Value(), "texture") == 0){
								String tname = "";
								if(pChild2->ToElement()->Attribute("name")) {
									tname =  pChild2->ToElement()->Attribute("name");
								}
								newShaderBinding->addTexture(tname, (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, pChild2->ToElement()->GetText()));
							}
							
							if(strcmp(pChild2->Value(), "cubemap") == 0){
								String tname = "";
								if(pChild2->ToElement()->Attribute("name")) {
									tname =  pChild2->ToElement()->Attribute("name");
								}
								newShaderBinding->addCubemap(tname, (Cubemap*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_CUBEMAP, pChild2->ToElement()->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;
}
示例#6
0
Material *MaterialManager::materialFromXMLNode(ResourcePool *resourcePool, 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);
	
	newMaterial->setResourceName(mname);
	
	if(nodeElement->Attribute("screen")) {
		if(String(nodeElement->Attribute("screen")) == "true") {
			newMaterial->screenMaterial = true;
		}
	}
    
	if(nodeElement->Attribute("wireframe")) {
		newMaterial->wireframe = String(nodeElement->Attribute("wireframe")) == "true";
	}
	
	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) {
								newTarget->sizeMode = ShaderRenderTarget::SIZE_MODE_NORMALIZED;	
								if(newTarget->width > 1.0f)
									newTarget->width = 1.0f;
								if(newTarget->height > 1.0f)
									newTarget->height = 1.0f;
							}						
						}
					}
					
					newTarget->normalizedWidth = -1;
					newTarget->normalizedHeight = -1;					
					newMaterial->recreateRenderTarget(newTarget);					
					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(resourcePool, 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) {
                                        param->setParamValueFromString(type, pvalue);
                                    }
								}
							}						
						}
					}
					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 if(strcmp(mode.c_str(), "color") == 0) {
									newBinding->mode = RenderTargetBinding::MODE_COLOR;
								} else if(strcmp(mode.c_str(), "depth") == 0) {
									newBinding->mode = RenderTargetBinding::MODE_DEPTH;
								} else {
									newBinding->mode = RenderTargetBinding::MODE_OUT;								
								}
																
								newShaderBinding->addRenderTargetBinding(newBinding);
								
								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;
									}
								}
								
								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*)resourcePool->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;
}