PolyMaterialManager.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * PolyMaterialManager.cpp
  3. * Poly
  4. *
  5. * Created by Ivan Safrin on 3/13/08.
  6. * Copyright 2008 __MyCompanyName__. All rights reserved.
  7. *
  8. */
  9. #include "PolyMaterialManager.h"
  10. using namespace Polycode;
  11. MaterialManager::MaterialManager() {
  12. }
  13. MaterialManager::~MaterialManager() {
  14. }
  15. void MaterialManager::Update(int elapsed) {
  16. for(int i=0;i < textures.size(); i++) {
  17. textures[i]->updateScroll(elapsed);
  18. }
  19. }
  20. Texture *MaterialManager::getTextureByResourcePath(String resourcePath) {
  21. for(int i=0;i < textures.size(); i++) {
  22. if(textures[i]->getResourcePath() == resourcePath)
  23. return textures[i];
  24. }
  25. return NULL;
  26. }
  27. //SceneRenderTexture *MaterialManager::createRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight) {
  28. // Texture *baseTexture = createTexture(renderWidth, renderHeight, NULL);
  29. // textures.push_back(baseTexture);
  30. // SceneRenderTexture *renderTexture = new SceneRenderTexture(baseTexture, targetScene, targetCamera, renderWidth, renderHeight);
  31. // return renderTexture;
  32. //}
  33. void MaterialManager::deleteTexture(Texture *texture) {
  34. for(int i=0;i < textures.size(); i++) {
  35. if(textures[i] == texture) {
  36. textures.erase(textures.begin()+i);
  37. delete texture;
  38. return;
  39. }
  40. }
  41. }
  42. void MaterialManager::reloadPrograms() {
  43. for(int m=0; m < shaderModules.size(); m++) {
  44. PolycodeShaderModule *shaderModule = shaderModules[m];
  45. shaderModule->reloadPrograms();
  46. }
  47. }
  48. void MaterialManager::addShaderModule(PolycodeShaderModule *module) {
  49. shaderModules.push_back(module);
  50. }
  51. Texture *MaterialManager::createTextureFromFile(String fileName, bool clamp) {
  52. Texture *newTexture;
  53. newTexture = getTextureByResourcePath(fileName);
  54. if(newTexture) {
  55. return newTexture;
  56. }
  57. Image *image = new Image(fileName);
  58. if(image->isLoaded()) {
  59. newTexture = createTexture(image->getWidth(), image->getHeight(), image->getPixels(), clamp);
  60. } else {
  61. char *data = (char*)malloc(4);
  62. newTexture = createTexture(1, 1, data, true);
  63. free(data);
  64. }
  65. delete image;
  66. vector<String> bits = fileName.split("/");
  67. newTexture->setResourcePath(bits[bits.size()-1]);
  68. return newTexture;
  69. }
  70. Texture *MaterialManager::createFramebufferTexture(int width, int height, int type) {
  71. Texture *newTexture = CoreServices::getInstance()->getRenderer()->createFramebufferTexture(width, height);
  72. return newTexture;
  73. }
  74. Texture *MaterialManager::createNewTexture(int width, int height, bool clamp, int type) {
  75. Image *newImage = new Image(width, height, type);
  76. newImage->fill(1,1,1,1);
  77. Texture *retTexture = createTextureFromImage(newImage, clamp);
  78. delete newImage;
  79. return retTexture;
  80. }
  81. Texture *MaterialManager::createTexture(int width, int height, char *imageData, bool clamp, int type) {
  82. Texture *newTexture = CoreServices::getInstance()->getRenderer()->createTexture(width, height, imageData,clamp, type);
  83. textures.push_back(newTexture);
  84. return newTexture;
  85. }
  86. Texture *MaterialManager::createTextureFromImage(Image *image, bool clamp) {
  87. Texture *newTexture;
  88. newTexture = createTexture(image->getWidth(), image->getHeight(), image->getPixels(),clamp, image->getType());
  89. return newTexture;
  90. }
  91. void MaterialManager::reloadProgramsAndTextures() {
  92. reloadTextures();
  93. reloadPrograms();
  94. }
  95. void MaterialManager::reloadTextures() {
  96. for(int i=0; i < textures.size(); i++) {
  97. Texture *texture = textures[i];
  98. texture->recreateFromImageData();
  99. }
  100. }
  101. void MaterialManager::loadMaterialsFromFile(String fileName) {
  102. }
  103. Shader *MaterialManager::createShaderFromXMLNode(TiXmlNode *node) {
  104. Shader *retShader = NULL;
  105. if(node->ToElement()->Attribute("type")) {
  106. String shaderType = node->ToElement()->Attribute("type");
  107. // Logger::log("Attempting to create %s shader\n", shaderType.c_str());
  108. for(int m=0; m < shaderModules.size(); m++) {
  109. PolycodeShaderModule *shaderModule = shaderModules[m];
  110. if(shaderModule->getShaderType() == shaderType) {
  111. retShader = shaderModule->createShader(node);
  112. }
  113. }
  114. }
  115. return retShader;
  116. }
  117. Shader *MaterialManager::setShaderFromXMLNode(TiXmlNode *node) {
  118. Shader *retShader = NULL;
  119. if(node->ToElement()->Attribute("type")) {
  120. String shaderType = node->ToElement()->Attribute("type");
  121. if(shaderType == "fixed") {
  122. FixedShader *fShader = new FixedShader();
  123. retShader = fShader;
  124. }
  125. } else {
  126. retShader = (Shader*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_SHADER, node->ToElement()->Attribute("name"));
  127. }
  128. return retShader;
  129. }
  130. // for (pChild = node->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
  131. // if(strcmp(pChild->Value(), "textures") == 0) {
  132. // for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
  133. // if(strcmp(pChild2->Value(), "texture") == 0)
  134. // fShader->setDiffuseTexture((Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, pChild2->ToElement()->GetText()));
  135. // }
  136. // }
  137. // }
  138. Cubemap *MaterialManager::cubemapFromXMLNode(TiXmlNode *node) {
  139. Cubemap *newCubemap;
  140. String name = node->ToElement()->Attribute("name");
  141. String mapString = node->ToElement()->GetText();
  142. vector<String> maps = mapString.split(",");
  143. if(maps.size() != 6) {
  144. Logger::log("Error: A cubemap must contain 6 images \n");
  145. return NULL;
  146. }
  147. newCubemap = CoreServices::getInstance()->getRenderer()->createCubemap(
  148. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, maps[0]),
  149. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, maps[1]),
  150. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, maps[2]),
  151. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, maps[3]),
  152. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, maps[4]),
  153. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, maps[5])
  154. );
  155. newCubemap->setResourceName(name);
  156. return newCubemap;
  157. }
  158. Material *MaterialManager::materialFromXMLNode(TiXmlNode *node) {
  159. String mname = node->ToElement()->Attribute("name");
  160. TiXmlNode* pChild, *pChild2,*pChild3;
  161. Shader *materialShader;
  162. ShaderBinding *newShaderBinding;
  163. vector<Shader*> materialShaders;
  164. vector<ShaderBinding*> newShaderBindings;
  165. vector<ShaderRenderTarget*> renderTargets;
  166. for (pChild3 = node->FirstChild(); pChild3 != 0; pChild3 = pChild3->NextSibling()) {
  167. if(strcmp(pChild3->Value(), "rendertargets") == 0) {
  168. for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
  169. if(strcmp(pChild->Value(), "rendertarget") == 0) {
  170. ShaderRenderTarget *newTarget = new ShaderRenderTarget;
  171. newTarget->id = pChild->ToElement()->Attribute("id");
  172. newTarget->width = CoreServices::getInstance()->getRenderer()->getXRes();
  173. newTarget->height = CoreServices::getInstance()->getRenderer()->getYRes();
  174. newTarget->sizeMode = ShaderRenderTarget::SIZE_MODE_PIXELS;
  175. if(pChild->ToElement()->Attribute("width") && pChild->ToElement()->Attribute("height")) {
  176. newTarget->width = atof(pChild->ToElement()->Attribute("width"));
  177. newTarget->height = atof(pChild->ToElement()->Attribute("height"));
  178. if(pChild->ToElement()->Attribute("sizeMode")) {
  179. if(strcmp(pChild->ToElement()->Attribute("sizeMode"), "normalized") == 0) {
  180. if(newTarget->width > 1.0f)
  181. newTarget->width = 1.0f;
  182. if(newTarget->height > 1.0f)
  183. newTarget->height = 1.0f;
  184. newTarget->width = ((Number)CoreServices::getInstance()->getRenderer()->getXRes()) * newTarget->width;
  185. newTarget->height = ((Number)CoreServices::getInstance()->getRenderer()->getYRes()) * newTarget->height;
  186. }
  187. }
  188. }
  189. // Texture *newTexture = CoreServices::getInstance()->getMaterialManager()->createNewTexture(newTarget->width, newTarget->height, true);
  190. Texture *newTexture, *temp;
  191. CoreServices::getInstance()->getRenderer()->createRenderTextures(&newTexture, &temp, (int)newTarget->width, (int)newTarget->height);
  192. newTexture->setResourceName(newTarget->id);
  193. //CoreServices::getInstance()->getResourceManager()->addResource(newTexture);
  194. newTarget->texture = newTexture;
  195. renderTargets.push_back(newTarget);
  196. }
  197. }
  198. }
  199. }
  200. for (pChild3 = node->FirstChild(); pChild3 != 0; pChild3 = pChild3->NextSibling()) {
  201. if(strcmp(pChild3->Value(), "shader") == 0) {
  202. materialShader = setShaderFromXMLNode(pChild3);
  203. if(materialShader) {
  204. newShaderBinding = materialShader->createBinding();
  205. materialShaders.push_back(materialShader);
  206. newShaderBindings.push_back(newShaderBinding);
  207. for (pChild = pChild3->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) {
  208. if(strcmp(pChild->Value(), "params") == 0) {
  209. for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
  210. if(strcmp(pChild2->Value(), "param") == 0){
  211. String pname = pChild2->ToElement()->Attribute("name");
  212. String ptype = pChild2->ToElement()->Attribute("type");
  213. String pvalue = pChild2->ToElement()->Attribute("value");
  214. newShaderBinding->addParam(ptype, pname, pvalue);
  215. }
  216. }
  217. }
  218. if(strcmp(pChild->Value(), "targettextures") == 0) {
  219. for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
  220. if(strcmp(pChild2->Value(), "targettexture") == 0){
  221. RenderTargetBinding* newBinding = new RenderTargetBinding;
  222. newBinding->id = pChild2->ToElement()->Attribute("id");
  223. newBinding->name = "";
  224. if(pChild2->ToElement()->Attribute("name")) {
  225. newBinding->name = pChild2->ToElement()->Attribute("name");
  226. }
  227. String mode = pChild2->ToElement()->Attribute("mode");
  228. if(strcmp(mode.c_str(), "in") == 0) {
  229. newBinding->mode = RenderTargetBinding::MODE_IN;
  230. } else {
  231. newBinding->mode = RenderTargetBinding::MODE_OUT;
  232. }
  233. newShaderBinding->addRenderTargetBinding(newBinding);
  234. //Texture *texture = (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, newBinding->id);
  235. // newBinding->texture = texture;
  236. for(int l=0; l < renderTargets.size(); l++) {
  237. if(renderTargets[l]->id == newBinding->id) {
  238. newBinding->texture = renderTargets[l]->texture;
  239. newBinding->width = renderTargets[l]->width;
  240. newBinding->height = renderTargets[l]->height;
  241. }
  242. }
  243. if(newBinding->mode == RenderTargetBinding::MODE_IN) {
  244. newShaderBinding->addTexture(newBinding->name, newBinding->texture);
  245. }
  246. }
  247. }
  248. }
  249. if(strcmp(pChild->Value(), "textures") == 0) {
  250. for (pChild2 = pChild->FirstChild(); pChild2 != 0; pChild2 = pChild2->NextSibling()) {
  251. if(strcmp(pChild2->Value(), "texture") == 0){
  252. String tname = "";
  253. if(pChild2->ToElement()->Attribute("name")) {
  254. tname = pChild2->ToElement()->Attribute("name");
  255. }
  256. newShaderBinding->addTexture(tname, (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, pChild2->ToElement()->GetText()));
  257. }
  258. if(strcmp(pChild2->Value(), "cubemap") == 0){
  259. String tname = "";
  260. if(pChild2->ToElement()->Attribute("name")) {
  261. tname = pChild2->ToElement()->Attribute("name");
  262. }
  263. newShaderBinding->addCubemap(tname, (Cubemap*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_CUBEMAP, pChild2->ToElement()->GetText()));
  264. }
  265. }
  266. }
  267. }
  268. }
  269. }
  270. }
  271. Material *newMaterial = new Material(mname);
  272. for(int i=0; i< materialShaders.size(); i++) {
  273. newMaterial->addShader(materialShaders[i],newShaderBindings[i]);
  274. }
  275. for(int i=0; i< renderTargets.size(); i++) {
  276. newMaterial->addShaderRenderTarget(renderTargets[i]);
  277. }
  278. return newMaterial;
  279. }