PolycodeMaterialEditor.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. /*
  2. Copyright (C) 2012 by Ivan Safrin
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. #include "PolycodeMaterialEditor.h"
  20. #include "PolycodeFrame.h"
  21. #include "PolyCubemap.h"
  22. extern UIColorPicker *globalColorPicker;
  23. extern UIGlobalMenu *globalMenu;
  24. extern PolycodeFrame *globalFrame;
  25. CubemapEditorPane::CubemapEditorPane() : UIElement() {
  26. currentCubemap = NULL;
  27. headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
  28. addChild(headerBg);
  29. headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  30. headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
  31. propList = new PropList("CUBEMAP EDITOR");
  32. addChild(propList);
  33. propList->setPosition(0, 0);
  34. PropSheet *baseProps1 = new PropSheet("CUBEMAP OPTIONS", "");
  35. propList->addPropSheet(baseProps1);
  36. nameProp = new StringProp("Name");
  37. baseProps1->addProp(nameProp);
  38. baseProps1->propHeight = 70;
  39. PropSheet *baseProps = new PropSheet("CUBEMAP TEXTURES", "");
  40. propList->addPropSheet(baseProps);
  41. xPosTexture = new TextureProp("X+");
  42. baseProps->addProp(xPosTexture);
  43. xNegTexture = new TextureProp("X-");
  44. baseProps->addProp(xNegTexture);
  45. yPosTexture = new TextureProp("Y+");
  46. baseProps->addProp(yPosTexture);
  47. yNegTexture = new TextureProp("Y-");
  48. baseProps->addProp(yNegTexture);
  49. zPosTexture = new TextureProp("Z+");
  50. baseProps->addProp(zPosTexture);
  51. zNegTexture = new TextureProp("Z-");
  52. baseProps->addProp(zNegTexture);
  53. nameProp->addEventListener(this, Event::CHANGE_EVENT);
  54. yPosTexture->addEventListener(this, Event::CHANGE_EVENT);
  55. yNegTexture->addEventListener(this, Event::CHANGE_EVENT);
  56. xPosTexture->addEventListener(this, Event::CHANGE_EVENT);
  57. xNegTexture->addEventListener(this, Event::CHANGE_EVENT);
  58. zPosTexture->addEventListener(this, Event::CHANGE_EVENT);
  59. zNegTexture->addEventListener(this, Event::CHANGE_EVENT);
  60. baseProps->propHeight = 220;
  61. propList->updateProps();
  62. cubemapPreview = new MaterialPreviewBox();
  63. addChild(cubemapPreview);
  64. cubemapPreview->setPosition(400, 0);
  65. Material *previewMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("CubemapPreview", "LightCube");
  66. cubemapPreview->setMaterial(previewMaterial);
  67. enabled = false;
  68. }
  69. void CubemapEditorPane::setCubemap(Cubemap *cubemap) {
  70. enabled = true;
  71. currentCubemap = cubemap;
  72. nameProp->set(cubemap->getResourceName());
  73. cubemapPreview->previewPrimitive->getLocalShaderOptions()->clearCubemap("lightCube");
  74. cubemapPreview->previewPrimitive->getLocalShaderOptions()->addCubemap("lightCube", cubemap);
  75. yPosTexture->set(cubemap->getTexture(Cubemap::CUBEMAP_YPOS));
  76. yNegTexture->set(cubemap->getTexture(Cubemap::CUBEMAP_YNEG));
  77. xPosTexture->set(cubemap->getTexture(Cubemap::CUBEMAP_XPOS));
  78. xNegTexture->set(cubemap->getTexture(Cubemap::CUBEMAP_XNEG));
  79. zPosTexture->set(cubemap->getTexture(Cubemap::CUBEMAP_ZPOS));
  80. zNegTexture->set(cubemap->getTexture(Cubemap::CUBEMAP_ZNEG));
  81. }
  82. void CubemapEditorPane::handleEvent(Event *event) {
  83. if(event->getDispatcher() == nameProp) {
  84. currentCubemap->setResourceName(nameProp->get());
  85. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  86. }
  87. if(event->getDispatcher() == yPosTexture) {
  88. currentCubemap->setTexture(yPosTexture->get(), Cubemap::CUBEMAP_YPOS);
  89. currentCubemap->recreateFromTextures();
  90. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  91. }
  92. if(event->getDispatcher() == yNegTexture) {
  93. currentCubemap->setTexture(yNegTexture->get(), Cubemap::CUBEMAP_YNEG);
  94. currentCubemap->recreateFromTextures();
  95. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  96. }
  97. if(event->getDispatcher() == xPosTexture) {
  98. currentCubemap->setTexture(xPosTexture->get(), Cubemap::CUBEMAP_XPOS);
  99. currentCubemap->recreateFromTextures();
  100. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  101. }
  102. if(event->getDispatcher() == xNegTexture) {
  103. currentCubemap->setTexture(xNegTexture->get(), Cubemap::CUBEMAP_XNEG);
  104. currentCubemap->recreateFromTextures();
  105. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  106. }
  107. if(event->getDispatcher() == zPosTexture) {
  108. currentCubemap->setTexture(zPosTexture->get(), Cubemap::CUBEMAP_ZPOS);
  109. currentCubemap->recreateFromTextures();
  110. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  111. }
  112. if(event->getDispatcher() == zNegTexture) {
  113. currentCubemap->setTexture(zNegTexture->get(), Cubemap::CUBEMAP_ZNEG);
  114. currentCubemap->recreateFromTextures();
  115. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  116. }
  117. }
  118. CubemapEditorPane::~CubemapEditorPane() {
  119. }
  120. void CubemapEditorPane::Resize(Number width, Number height) {
  121. headerBg->setShapeSize(width, 30);
  122. propList->Resize(370, height);
  123. propList->updateProps();
  124. }
  125. ShaderEditorPane::ShaderEditorPane() : UIElement() {
  126. changingShader = false;
  127. currentShader = NULL;
  128. headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
  129. addChild(headerBg);
  130. headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  131. headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
  132. propList = new PropList("SHADER EDITOR");
  133. addChild(propList);
  134. propList->setPosition(0, 0);
  135. PropSheet *baseProps = new PropSheet("SHADER SETTINGS", "");
  136. propList->addPropSheet(baseProps);
  137. nameProp = new StringProp("Name");
  138. baseProps->addProp(nameProp);
  139. nameProp->addEventListener(this, Event::CHANGE_EVENT);
  140. screenShaderProp = new BoolProp("Screen shader");
  141. baseProps->addProp(screenShaderProp);
  142. screenShaderProp->addEventListener(this, Event::CHANGE_EVENT);
  143. vertexProgramProp = new ComboProp("Vertex prog.");
  144. baseProps->addProp(vertexProgramProp);
  145. vertexProgramProp->addEventListener(this, Event::CHANGE_EVENT);
  146. fragmentProgramProp = new ComboProp("Fragment prog.");
  147. baseProps->addProp(fragmentProgramProp);
  148. fragmentProgramProp->addEventListener(this, Event::CHANGE_EVENT);
  149. areaLightsProp = new NumberProp("Num area lights");
  150. baseProps->addProp(areaLightsProp);
  151. areaLightsProp->addEventListener(this, Event::CHANGE_EVENT);
  152. spotLightsProp = new NumberProp("Num spotlights");
  153. baseProps->addProp(spotLightsProp);
  154. spotLightsProp->addEventListener(this, Event::CHANGE_EVENT);
  155. baseProps->propHeight = 220;
  156. PropSheet *vertexProps = new PropSheet("VERTEX PROGRAM OPTIONS", "");
  157. propList->addPropSheet(vertexProps);
  158. PropSheet *fragmentProps = new PropSheet("FRAGMENT PROGRAM OPTIONS", "");
  159. propList->addPropSheet(fragmentProps);
  160. propList->updateProps();
  161. enabled = false;
  162. }
  163. ShaderEditorPane::~ShaderEditorPane() {
  164. }
  165. void ShaderEditorPane::handleEvent(Event *event) {
  166. if(!changingShader) {
  167. if(event->getDispatcher() == nameProp) {
  168. currentShader->setName(nameProp->get());
  169. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  170. }
  171. if(event->getDispatcher() == screenShaderProp) {
  172. currentShader->screenShader = screenShaderProp->get();
  173. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  174. }
  175. if(event->getDispatcher() == areaLightsProp) {
  176. currentShader->numAreaLights = floor(areaLightsProp->get());
  177. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  178. }
  179. if(event->getDispatcher() == spotLightsProp) {
  180. currentShader->numSpotLights = floor(spotLightsProp->get());
  181. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  182. }
  183. if(event->getDispatcher() == vertexProgramProp) {
  184. ShaderProgram* vpProgram = (ShaderProgram*)vertexProgramProp->comboEntry->getSelectedItem()->data;
  185. if(vpProgram) {
  186. currentShader->setVertexProgram(vpProgram);
  187. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  188. } else {
  189. globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
  190. std::vector<String> extensions;
  191. extensions.push_back("vert");
  192. choosingVertexProgram = true;
  193. globalFrame->showAssetBrowser(extensions);
  194. }
  195. }
  196. if(event->getDispatcher() == fragmentProgramProp) {
  197. ShaderProgram* fpProgram = (ShaderProgram*)fragmentProgramProp->comboEntry->getSelectedItem()->data;
  198. if(fpProgram) {
  199. currentShader->setFragmentProgram(fpProgram);
  200. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  201. } else {
  202. globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
  203. std::vector<String> extensions;
  204. extensions.push_back("frag");
  205. choosingVertexProgram = false;
  206. globalFrame->showAssetBrowser(extensions);
  207. }
  208. }
  209. }
  210. if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
  211. String newProgramPath = globalFrame->assetBrowser->getFullSelectedAssetPath();
  212. globalFrame->assetBrowser->removeAllHandlersForListener(this);
  213. OSFileEntry entry(newProgramPath, OSFileEntry::TYPE_FILE);
  214. ShaderProgram *newProgram = CoreServices::getInstance()->getMaterialManager()->createProgramFromFile(newProgramPath);
  215. newProgram->reloadOnFileModify = true;
  216. if(newProgram) {
  217. newProgram->setResourceName(entry.name);
  218. newProgram->setResourcePath(newProgramPath);
  219. CoreServices::getInstance()->getResourceManager()->addResource(newProgram);
  220. }
  221. if(choosingVertexProgram) {
  222. currentShader->setVertexProgram(newProgram);
  223. } else {
  224. currentShader->setFragmentProgram(newProgram);
  225. }
  226. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  227. globalFrame->hideModal();
  228. reloadPrograms();
  229. }
  230. }
  231. void ShaderEditorPane::reloadPrograms() {
  232. vertexProgramProp->comboEntry->clearItems();
  233. fragmentProgramProp->comboEntry->clearItems();
  234. vertexProgramProp->comboEntry->addComboItem("Custom...", NULL);
  235. fragmentProgramProp->comboEntry->addComboItem("Custom...", NULL);
  236. std::vector<Resource*> programs = CoreServices::getInstance()->getResourceManager()->getResources(Resource::RESOURCE_PROGRAM);
  237. for(int i=0; i < programs.size(); i++) {
  238. ShaderProgram* program = (ShaderProgram*) programs[i];
  239. if(program->type == ShaderProgram::TYPE_VERT) {
  240. vertexProgramProp->comboEntry->addComboItem(program->getResourceName(), (void*)program);
  241. if(program == currentShader->vp) {
  242. vertexProgramProp->comboEntry->setSelectedIndex(vertexProgramProp->comboEntry->getNumItems()-1);
  243. }
  244. } else if(program->type == ShaderProgram::TYPE_FRAG) {
  245. fragmentProgramProp->comboEntry->addComboItem(program->getResourceName(), (void*)program);
  246. if(program == currentShader->fp) {
  247. fragmentProgramProp->comboEntry->setSelectedIndex(fragmentProgramProp->comboEntry->getNumItems()-1);
  248. }
  249. }
  250. }
  251. }
  252. void ShaderEditorPane::setShader(Shader *shader) {
  253. changingShader = true;
  254. currentShader = shader;
  255. reloadPrograms();
  256. nameProp->set(shader->getName());
  257. for(int i=0; i < vertexProgramProp->comboEntry->getNumItems(); i++) {
  258. ShaderProgram* program = (ShaderProgram*) vertexProgramProp->comboEntry->getItemAtIndex(i)->data;
  259. if(program == shader->vp) {
  260. vertexProgramProp->comboEntry->setSelectedIndex(i);
  261. }
  262. }
  263. for(int i=0; i < fragmentProgramProp->comboEntry->getNumItems(); i++) {
  264. ShaderProgram* program = (ShaderProgram*) fragmentProgramProp->comboEntry->getItemAtIndex(i)->data;
  265. if(program == shader->fp) {
  266. fragmentProgramProp->comboEntry->setSelectedIndex(i);
  267. }
  268. }
  269. screenShaderProp->set(shader->screenShader);
  270. areaLightsProp->set(shader->numAreaLights);
  271. spotLightsProp->set(shader->numSpotLights);
  272. enabled = true;
  273. changingShader = false;
  274. }
  275. void ShaderEditorPane::Resize(Number width, Number height) {
  276. headerBg->setShapeSize(width, 30);
  277. propList->Resize(370, height);
  278. propList->updateProps();
  279. }
  280. MaterialPreviewBox::MaterialPreviewBox() : UIElement() {
  281. currentMaterial = NULL;
  282. previewScene = new Scene(true);
  283. renderTexture = new SceneRenderTexture(previewScene, previewScene->getDefaultCamera(), 512, 512);
  284. ScenePrimitive *previewBg = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 15.0, 15.0, 15.0);
  285. previewBg->Yaw(45.0);
  286. previewBg->backfaceCulled = false;
  287. Material *bgMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("MaterialEditorBg", "Unlit");
  288. previewBg->setMaterial(bgMaterial);
  289. Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("Images/material_grid.png");
  290. previewBg->getLocalShaderOptions()->addTexture("diffuse", tex);
  291. previewScene->addChild(previewBg);
  292. previewScene->clearColor.setColor(0.1, 0.1, 0.1, 0.0);
  293. previewScene->ambientColor.setColor(0.2, 0.2, 0.2, 1.0);
  294. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_TORUS, 3.0, 1.2, 26, 16);
  295. previewScene->addChild(previewPrimitive);
  296. shapePrimitives.push_back(previewPrimitive);
  297. previewPrimitive->getMesh()->calculateTangents();
  298. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_SPHERE, 3.0, 16, 16);
  299. previewScene->addChild(previewPrimitive);
  300. shapePrimitives.push_back(previewPrimitive);
  301. previewPrimitive->getMesh()->calculateTangents();
  302. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 4.0, 4.0, 4.0);
  303. previewPrimitive->Yaw(45.0);
  304. previewPrimitive->getMesh()->calculateNormals(false);
  305. previewPrimitive->getMesh()->calculateTangents();
  306. previewScene->addChild(previewPrimitive);
  307. shapePrimitives.push_back(previewPrimitive);
  308. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 6.0, 6.0);
  309. previewPrimitive->billboardMode = true;
  310. previewScene->addChild(previewPrimitive);
  311. shapePrimitives.push_back(previewPrimitive);
  312. previewPrimitive->getMesh()->calculateTangents();
  313. mainLight = new SceneLight(SceneLight::AREA_LIGHT, previewScene, 290.0);
  314. mainLight->setPosition(-10,10,10);
  315. previewScene->addLight(mainLight);
  316. secondLight = new SceneLight(SceneLight::AREA_LIGHT, previewScene, 250.0);
  317. secondLight->setPosition(10,-10,10);
  318. previewScene->addLight(secondLight);
  319. previewScene->getDefaultCamera()->setPosition(0,7,9);
  320. previewScene->getDefaultCamera()->lookAt(Vector3());
  321. previewBase = new ScreenEntity();
  322. previewBase->processInputEvents = true;
  323. previewBase->setPosition(0, 0);
  324. addChild(previewBase);
  325. previewShape = new ScreenShape(ScreenShape::SHAPE_RECT, 256, 256);
  326. previewShape->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  327. previewShape->setTexture(renderTexture->getTargetTexture());
  328. previewShape->setPosition(20,40);
  329. previewShape->strokeEnabled = true;
  330. previewShape->strokeColor = Color(1.0, 1.0, 1.0, 0.2);
  331. previewShape->setStrokeWidth(1.0);
  332. previewBase->addChild(previewShape);
  333. shapeSelector = new ScreenImage("Images/small_selector.png");
  334. previewBase->addChild(shapeSelector);
  335. shapeSelector->color.a = 0.4;
  336. shapeSwitches.push_back(new UIImageButton("Images/torus_icon.png"));
  337. shapeSwitches.push_back(new UIImageButton("Images/sphere_icon.png"));
  338. shapeSwitches.push_back(new UIImageButton("Images/box_icon.png"));
  339. shapeSwitches.push_back(new UIImageButton("Images/plane_icon.png"));
  340. for(int i=0; i < shapeSwitches.size(); i++) {
  341. previewBase->addChild(shapeSwitches[i]);
  342. shapeSwitches[i]->setPosition(105 + (25 * i), 300);
  343. shapeSwitches[i]->addEventListener(this, UIEvent::CLICK_EVENT);
  344. }
  345. showPrimitive(0);
  346. }
  347. void MaterialPreviewBox::clearMaterial() {
  348. previewPrimitive->clearMaterial();
  349. }
  350. MaterialPreviewBox::~MaterialPreviewBox() {
  351. }
  352. void MaterialPreviewBox::setMaterial(Material *material) {
  353. currentMaterial = material;
  354. previewPrimitive->setMaterial(material);
  355. }
  356. void MaterialPreviewBox::showPrimitive(unsigned int index) {
  357. for(int i=0; i < shapePrimitives.size(); i++) {
  358. shapePrimitives[i]->visible = false;
  359. }
  360. shapePrimitives[index]->visible = true;
  361. shapeSelector->setPosition(105 - 2 + (25 * index), 298);
  362. if(currentMaterial) {
  363. shapePrimitives[index]->setMaterial(currentMaterial);
  364. }
  365. previewPrimitive = shapePrimitives[index];
  366. }
  367. void MaterialPreviewBox::handleEvent(Event *event) {
  368. for(int i=0; i < shapeSwitches.size(); i++) {
  369. if(event->getDispatcher() == shapeSwitches[i]) {
  370. if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  371. showPrimitive(i);
  372. }
  373. }
  374. }
  375. }
  376. MaterialEditorPane::MaterialEditorPane() : UIElement() {
  377. changingMaterial = false;
  378. headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
  379. addChild(headerBg);
  380. headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  381. headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
  382. propList = new PropList("MATERIAL EDITOR");
  383. addChild(propList);
  384. propList->setPosition(0, 0);
  385. PropSheet *baseProps = new PropSheet("MATERIAL SETTINGS", "");
  386. propList->addPropSheet(baseProps);
  387. nameProp = new StringProp("Name");
  388. baseProps->addProp(nameProp);
  389. nameProp->addEventListener(this, Event::CHANGE_EVENT);
  390. shaderProp = new ComboProp("Shader");
  391. baseProps->addProp(shaderProp);
  392. shaderProp->addEventListener(this, Event::CHANGE_EVENT);
  393. blendModeProp = new ComboProp("Blend mode");
  394. baseProps->addProp(blendModeProp);
  395. blendModeProp->addEventListener(this, Event::CHANGE_EVENT);
  396. blendModeProp->comboEntry->addComboItem("Normal");
  397. blendModeProp->comboEntry->addComboItem("Lighten");
  398. blendModeProp->comboEntry->addComboItem("Color");
  399. blendModeProp->comboEntry->addComboItem("Premultiplied");
  400. blendModeProp->comboEntry->addComboItem("Multiply");
  401. baseProps->propHeight = 130;
  402. shaderTextureSheet = new ShaderTexturesSheet();
  403. propList->addPropSheet(shaderTextureSheet);
  404. shaderTextureSheet->addEventListener(this, Event::CHANGE_EVENT);
  405. shaderOptionsSheet = new ShaderOptionsSheet("SHADER OPTIONS", "shader_options");
  406. propList->addPropSheet(shaderOptionsSheet);
  407. shaderOptionsSheet->addEventListener(this, Event::CHANGE_EVENT);
  408. propList->updateProps();
  409. materialPreview = new MaterialPreviewBox();
  410. addChild(materialPreview);
  411. materialPreview->setPosition(400, 0);
  412. Config *conf = CoreServices::getInstance()->getConfig();
  413. String fontName = conf->getStringValue("Polycode", "uiDefaultFontName");
  414. currentMaterial = NULL;
  415. reloadShaders();
  416. enabled = false;
  417. }
  418. void MaterialEditorPane::reloadShaders() {
  419. shaderProp->comboEntry->clearItems();
  420. MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
  421. for(int i=0; i < materialManager->getNumShaders(); i++) {
  422. if(!materialManager->getShaderByIndex(i)->screenShader) {
  423. shaderProp->comboEntry->addComboItem(materialManager->getShaderByIndex(i)->getName(), (void*)materialManager->getShaderByIndex(i));
  424. }
  425. }
  426. }
  427. void MaterialEditorPane::Resize(Number width, Number height) {
  428. headerBg->setShapeSize(width, 30);
  429. propList->Resize(370, height);
  430. propList->updateProps();
  431. }
  432. void MaterialEditorPane::handleEvent(Event *event) {
  433. if(event->getDispatcher() == currentMaterial) {
  434. shaderTextureSheet->setShader(currentMaterial->getShader(0), currentMaterial);
  435. shaderOptionsSheet->setShader(currentMaterial->getShader(0), currentMaterial);
  436. }
  437. if(event->getDispatcher() == shaderTextureSheet || event->getDispatcher() == shaderOptionsSheet) {
  438. if(!changingMaterial) {
  439. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  440. }
  441. } else if(event->getDispatcher() == blendModeProp) {
  442. currentMaterial->blendingMode = blendModeProp->get();
  443. if(!changingMaterial) {
  444. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  445. }
  446. } else if(event->getDispatcher() == nameProp) {
  447. currentMaterial->setName(nameProp->get());
  448. if(!changingMaterial) {
  449. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  450. }
  451. } else if(event->getDispatcher() == shaderProp) {
  452. Shader *selectedShader = (Shader*)shaderProp->comboEntry->getSelectedItem()->data;
  453. if(selectedShader) {
  454. if(currentMaterial->getShader(0) != selectedShader) {
  455. currentMaterial->clearShaders();
  456. materialPreview->clearMaterial();
  457. ShaderBinding *newShaderBinding = selectedShader->createBinding();
  458. currentMaterial->addShader(selectedShader, newShaderBinding);
  459. materialPreview->setMaterial(currentMaterial);
  460. }
  461. shaderTextureSheet->setShader(selectedShader, currentMaterial);
  462. shaderOptionsSheet->setShader(selectedShader, currentMaterial);
  463. }
  464. if(!changingMaterial) {
  465. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  466. }
  467. }
  468. }
  469. void MaterialEditorPane::setMaterial(Material *material) {
  470. changingMaterial = true;
  471. if(currentMaterial) {
  472. currentMaterial->removeAllHandlersForListener(this);
  473. }
  474. currentMaterial = material;
  475. materialPreview->setMaterial(material);
  476. material->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
  477. reloadShaders();
  478. if(!currentMaterial)
  479. return;
  480. blendModeProp->set(currentMaterial->blendingMode);
  481. if(currentMaterial->getShader(0)) {
  482. for(int i=0; i < shaderProp->comboEntry->getNumItems(); i++) {
  483. Shader *shader = (Shader*)shaderProp->comboEntry->getItemAtIndex(i)->data;
  484. if(shader) {
  485. if(currentMaterial->getShader(0)->getName() == shader->getName()) {
  486. shaderProp->set(i);
  487. shaderProp->dispatchEvent(new Event(), Event::CHANGE_EVENT);
  488. break;
  489. }
  490. }
  491. }
  492. } else {
  493. shaderProp->set(0);
  494. shaderProp->dispatchEvent(new Event(), Event::CHANGE_EVENT);
  495. }
  496. nameProp->set(currentMaterial->getName());
  497. enabled = true;
  498. changingMaterial = false;
  499. }
  500. MaterialEditorPane::~MaterialEditorPane() {
  501. }
  502. MaterialMainWindow::MaterialMainWindow() : UIElement() {
  503. materialPane = new MaterialEditorPane();
  504. shaderPane = new ShaderEditorPane();
  505. cubemapPane = new CubemapEditorPane();
  506. addChild(materialPane);
  507. addChild(shaderPane);
  508. addChild(cubemapPane);
  509. enableScissor = true;
  510. }
  511. void MaterialMainWindow::Resize(Number width, Number height) {
  512. Vector2 pos = getScreenPosition();
  513. scissorBox.setRect(pos.x,pos.y,width, height);
  514. materialPane->Resize(width, height);
  515. shaderPane->Resize(width, height);
  516. cubemapPane->Resize(width, height);
  517. }
  518. MaterialBrowser::MaterialBrowser() : UIElement() {
  519. treeContainer = new UITreeContainer("boxIcon.png", L"Material Library", 200, 555);
  520. treeContainer->getRootNode()->toggleCollapsed();
  521. treeContainer->getRootNode()->addEventListener(this, UITreeEvent::SELECTED_EVENT);
  522. treeContainer->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
  523. shadersNode = treeContainer->getRootNode()->addTreeChild("Images/shader_icon.png", "Shaders", NULL);
  524. materialsNode = treeContainer->getRootNode()->addTreeChild("Images/material_icon.png", "Materials", NULL);
  525. cubemapsNode = treeContainer->getRootNode()->addTreeChild("Images/cubemap_icon.png", "Cubemaps", NULL);
  526. postEffectsNode = treeContainer->getRootNode()->addTreeChild("folder.png", "Post Effects", NULL);
  527. addChild(treeContainer);
  528. selectedData = NULL;
  529. headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
  530. addChild(headerBg);
  531. headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  532. headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
  533. newShaderButton = new UIImageButton("Images/new_shader.png");
  534. addChild(newShaderButton);
  535. newShaderButton->setPosition(5,4);
  536. newMaterialButton = new UIImageButton("Images/new_material.png");
  537. addChild(newMaterialButton);
  538. newMaterialButton->setPosition(32,4);
  539. newCubemapButton = new UIImageButton("Images/new_cubemap.png");
  540. addChild(newCubemapButton);
  541. newCubemapButton->setPosition(59,4);
  542. selectedNode = NULL;
  543. }
  544. void MaterialBrowser::handleEvent(Event *event) {
  545. if(event->getDispatcher() == treeContainer->getRootNode()) {
  546. if(event->getEventCode() == UITreeEvent::SELECTED_EVENT){
  547. selectedNode = treeContainer->getRootNode()->getSelectedNode();
  548. MaterialBrowserData *data = (MaterialBrowserData *)selectedNode->getUserData();
  549. selectedData = data;
  550. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  551. }
  552. }
  553. ScreenEntity::handleEvent(event);
  554. }
  555. UITree *MaterialBrowser::addMaterial(Material *material) {
  556. MaterialBrowserData *data = new MaterialBrowserData();
  557. data->material = material;
  558. return materialsNode->addTreeChild("material_icon.png", material->getName(), (void*)data);
  559. }
  560. UITree *MaterialBrowser::addShader(Shader *shader) {
  561. MaterialBrowserData *data = new MaterialBrowserData();
  562. data->shader = shader;
  563. return shadersNode->addTreeChild("shader_icon.png", shader->getName(), (void*)data);
  564. }
  565. UITree *MaterialBrowser::addCubemap(Cubemap *cubemap) {
  566. MaterialBrowserData *data = new MaterialBrowserData();
  567. data->cubemap = cubemap;
  568. return cubemapsNode->addTreeChild("cubemap_icon.png", cubemap->getResourceName(), (void*)data);
  569. }
  570. MaterialBrowser::~MaterialBrowser() {
  571. }
  572. void MaterialBrowser::Resize(Number width, Number height) {
  573. treeContainer->Resize(width, height-30);
  574. treeContainer->setPosition(0, 30);
  575. headerBg->setShapeSize(width, 30);
  576. }
  577. PolycodeMaterialEditor::PolycodeMaterialEditor() : PolycodeEditor(true){
  578. selectedMaterialNode = NULL;
  579. }
  580. PolycodeMaterialEditor::~PolycodeMaterialEditor() {
  581. }
  582. bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
  583. mainSizer = new UIHSizer(100,100,200,false);
  584. addChild(mainSizer);
  585. materialBrowser = new MaterialBrowser();
  586. mainSizer->addRightChild(materialBrowser);
  587. materialBrowser->addEventListener(this, Event::CHANGE_EVENT);
  588. shaders = CoreServices::getInstance()->getMaterialManager()->loadShadersFromFile(filePath.fullPath);
  589. for(int i=0; i < shaders.size(); i++) {
  590. materialBrowser->addShader(shaders[i]);
  591. CoreServices::getInstance()->getMaterialManager()->addShader(shaders[i]);
  592. }
  593. cubemaps = CoreServices::getInstance()->getMaterialManager()->loadCubemapsFromFile(filePath.fullPath);
  594. for(int i=0; i < cubemaps.size(); i++) {
  595. materialBrowser->addCubemap(cubemaps[i]);
  596. CoreServices::getInstance()->getResourceManager()->addResource(cubemaps[i]);
  597. }
  598. materials = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(filePath.fullPath);
  599. for(int i=0; i < materials.size(); i++) {
  600. materialBrowser->addMaterial(materials[i]);
  601. }
  602. mainWindow = new MaterialMainWindow();
  603. mainSizer->addLeftChild(mainWindow);
  604. mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
  605. mainWindow->shaderPane->addEventListener(this, Event::CHANGE_EVENT);
  606. mainWindow->cubemapPane->addEventListener(this, Event::CHANGE_EVENT);
  607. mainWindow->shaderPane->parentProject = parentProject;
  608. materialBrowser->newMaterialButton->addEventListener(this, UIEvent::CLICK_EVENT);
  609. materialBrowser->newShaderButton->addEventListener(this, UIEvent::CLICK_EVENT);
  610. materialBrowser->newCubemapButton->addEventListener(this, UIEvent::CLICK_EVENT);
  611. mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
  612. PolycodeEditor::openFile(filePath);
  613. return true;
  614. }
  615. String PolycodeMaterialEditor::createStringValue(unsigned int type, void *value) {
  616. String retString;
  617. switch(type) {
  618. case ProgramParam::PARAM_NUMBER:
  619. retString = String::NumberToString(*((Number*)value));
  620. break;
  621. case ProgramParam::PARAM_COLOR:
  622. {
  623. Color color = *((Color*)value);
  624. retString = String::NumberToString(color.r) + " " + String::NumberToString(color.g) + " " + String::NumberToString(color.b) + " " + String::NumberToString(color.a);
  625. }
  626. break;
  627. case ProgramParam::PARAM_VECTOR2:
  628. {
  629. Vector2 vec = *((Vector2*)value);
  630. retString = String::NumberToString(vec.x) + " " + String::NumberToString(vec.y);
  631. }
  632. break;
  633. case ProgramParam::PARAM_VECTOR3:
  634. {
  635. Vector3 vec = *((Vector3*)value);
  636. retString = String::NumberToString(vec.x) + " " + String::NumberToString(vec.y) + " " + String::NumberToString(vec.z);
  637. }
  638. break;
  639. }
  640. return retString;
  641. }
  642. void PolycodeMaterialEditor::saveFile() {
  643. Object fileData;
  644. fileData.root.name = "polycode_material_library";
  645. ObjectEntry *cubemapsEntry = fileData.root.addChild("cubemaps");
  646. for(int i=0; i < cubemaps.size(); i++) {
  647. ObjectEntry *cubemapEntry = cubemapsEntry->addChild("cubemap");
  648. cubemapEntry->addChild("name", cubemaps[i]->getResourceName());
  649. cubemapEntry->addChild("xPos", cubemaps[i]->getTexture(Cubemap::CUBEMAP_XPOS)->getResourcePath());
  650. cubemapEntry->addChild("xNeg", cubemaps[i]->getTexture(Cubemap::CUBEMAP_XNEG)->getResourcePath());
  651. cubemapEntry->addChild("yPos", cubemaps[i]->getTexture(Cubemap::CUBEMAP_YPOS)->getResourcePath());
  652. cubemapEntry->addChild("yNeg", cubemaps[i]->getTexture(Cubemap::CUBEMAP_YNEG)->getResourcePath());
  653. cubemapEntry->addChild("zPos", cubemaps[i]->getTexture(Cubemap::CUBEMAP_ZPOS)->getResourcePath());
  654. cubemapEntry->addChild("zNeg", cubemaps[i]->getTexture(Cubemap::CUBEMAP_ZNEG)->getResourcePath());
  655. }
  656. ObjectEntry *materialsEntry = fileData.root.addChild("materials");
  657. for(int i=0; i < materials.size(); i++) {
  658. Material *material = materials[i];
  659. ObjectEntry *materialEntry = materialsEntry->addChild("material");
  660. materialEntry->addChild("name", material->getName());
  661. materialEntry->addChild("blendingMode", material->blendingMode);
  662. if(material->getShader(0) && material->getShaderBinding(0)) {
  663. Shader *shader = material->getShader(0);
  664. ObjectEntry *shaderEntry = materialEntry->addChild("shader");
  665. shaderEntry->addChild("name", shader->getName());
  666. ObjectEntry *texturesEntry = shaderEntry->addChild("textures");
  667. ShaderBinding *shaderBinding = material->getShaderBinding(0);
  668. for(int j=0; j < shader->expectedTextures.size(); j++) {
  669. Texture *texture = shaderBinding->getTexture(shader->expectedTextures[j]);
  670. if(texture) {
  671. String texturePath = texture->getResourcePath();
  672. texturePath = texturePath.replace(parentProject->getRootFolder()+"/", "");
  673. ObjectEntry *textureEntry = texturesEntry->addChild("texture", texturePath);
  674. textureEntry->addChild("name", shader->expectedTextures[j]);
  675. }
  676. }
  677. if(shader->expectedParams.size() > 0 || shader->expectedParams.size() > 0) {
  678. ObjectEntry *paramsEntry = shaderEntry->addChild("params");
  679. for(int j=0; j < shader->expectedParams.size(); j++) {
  680. if(shaderBinding->getLocalParamByName(shader->expectedParams[j].name)) {
  681. ObjectEntry *paramEntry = paramsEntry->addChild("param");
  682. paramEntry->addChild("name", shader->expectedParams[j].name);
  683. paramEntry->addChild("value", createStringValue(shader->expectedParams[j].type, shaderBinding->getLocalParamByName(shader->expectedParams[j].name)->data));
  684. }
  685. }
  686. }
  687. }
  688. }
  689. fileData.saveToXML(filePath);
  690. setHasChanges(false);
  691. }
  692. void PolycodeMaterialEditor::handleEvent(Event *event) {
  693. if(event->getDispatcher() == mainWindow->materialPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  694. if(selectedMaterialNode && mainWindow->materialPane->currentMaterial) {
  695. selectedMaterialNode->setLabelText(mainWindow->materialPane->currentMaterial->getName());
  696. }
  697. setHasChanges(true);
  698. }
  699. if(event->getDispatcher() == mainWindow->shaderPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  700. if(selectedMaterialNode && mainWindow->shaderPane->currentShader) {
  701. selectedMaterialNode->setLabelText(mainWindow->shaderPane->currentShader->getName());
  702. }
  703. setHasChanges(true);
  704. }
  705. if(event->getDispatcher() == mainWindow->cubemapPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  706. if(selectedMaterialNode && mainWindow->cubemapPane->currentCubemap) {
  707. selectedMaterialNode->setLabelText(mainWindow->cubemapPane->currentCubemap->getResourceName());
  708. }
  709. setHasChanges(true);
  710. }
  711. if(event->getDispatcher() == materialBrowser->newMaterialButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  712. Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("Untitled", "DefaultShader");
  713. materialBrowser->addMaterial(newMaterial)->setSelected();
  714. materials.push_back(newMaterial);
  715. setHasChanges(true);
  716. }
  717. if(event->getDispatcher() == materialBrowser->newShaderButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  718. Shader *newShader = CoreServices::getInstance()->getMaterialManager()->createShader("glsl", "Untitled", "Unlit.vert", "Unlit.frag", false);
  719. if(newShader) {
  720. materialBrowser->addShader(newShader);
  721. shaders.push_back(newShader);
  722. CoreServices::getInstance()->getMaterialManager()->addShader(newShader);
  723. setHasChanges(true);
  724. } else {
  725. printf("Error creating shader!\n");
  726. }
  727. }
  728. if(event->getDispatcher() == materialBrowser->newCubemapButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  729. Cubemap *cubemap = CoreServices::getInstance()->getRenderer()->createCubemap(
  730. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  731. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  732. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  733. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  734. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  735. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"));
  736. cubemap->setResourceName("Cubemap"+String::IntToString(cubemaps.size()));
  737. cubemaps.push_back(cubemap);
  738. materialBrowser->addCubemap(cubemap);
  739. setHasChanges(true);
  740. CoreServices::getInstance()->getResourceManager()->addResource(cubemap);
  741. }
  742. if(event->getDispatcher() == materialBrowser) {
  743. if(event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  744. if(materialBrowser->selectedData) {
  745. mainWindow->materialPane->enabled = false;
  746. mainWindow->shaderPane->enabled = false;
  747. mainWindow->cubemapPane->enabled = false;
  748. if(materialBrowser->selectedData->material) {
  749. selectedMaterialNode = materialBrowser->selectedNode;
  750. mainWindow->materialPane->setMaterial(materialBrowser->selectedData->material);
  751. } else if(materialBrowser->selectedData->shader) {
  752. selectedMaterialNode = materialBrowser->selectedNode;
  753. mainWindow->shaderPane->setShader(materialBrowser->selectedData->shader);
  754. } else if(materialBrowser->selectedData->cubemap) {
  755. selectedMaterialNode = materialBrowser->selectedNode;
  756. mainWindow->cubemapPane->setCubemap(materialBrowser->selectedData->cubemap);
  757. }
  758. }
  759. }
  760. }
  761. }
  762. void PolycodeMaterialEditor::Resize(int x, int y) {
  763. mainSizer->Resize(x,y);
  764. PolycodeEditor::Resize(x,y);
  765. }