2
0

PolycodeMaterialEditor.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  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. propList->updateProps();
  157. enabled = false;
  158. }
  159. ShaderEditorPane::~ShaderEditorPane() {
  160. }
  161. void ShaderEditorPane::handleEvent(Event *event) {
  162. if(!changingShader) {
  163. if(event->getDispatcher() == nameProp) {
  164. currentShader->setName(nameProp->get());
  165. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  166. }
  167. if(event->getDispatcher() == screenShaderProp) {
  168. currentShader->screenShader = screenShaderProp->get();
  169. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  170. }
  171. if(event->getDispatcher() == areaLightsProp) {
  172. currentShader->numAreaLights = floor(areaLightsProp->get());
  173. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  174. }
  175. if(event->getDispatcher() == spotLightsProp) {
  176. currentShader->numSpotLights = floor(spotLightsProp->get());
  177. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  178. }
  179. if(event->getDispatcher() == vertexProgramProp) {
  180. ShaderProgram* vpProgram = (ShaderProgram*)vertexProgramProp->comboEntry->getSelectedItem()->data;
  181. if(vpProgram) {
  182. currentShader->setVertexProgram(vpProgram);
  183. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  184. } else {
  185. globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
  186. std::vector<String> extensions;
  187. extensions.push_back("vert");
  188. choosingVertexProgram = true;
  189. globalFrame->showAssetBrowser(extensions);
  190. }
  191. }
  192. if(event->getDispatcher() == fragmentProgramProp) {
  193. ShaderProgram* fpProgram = (ShaderProgram*)fragmentProgramProp->comboEntry->getSelectedItem()->data;
  194. if(fpProgram) {
  195. currentShader->setFragmentProgram(fpProgram);
  196. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  197. } else {
  198. globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
  199. std::vector<String> extensions;
  200. extensions.push_back("frag");
  201. choosingVertexProgram = false;
  202. globalFrame->showAssetBrowser(extensions);
  203. }
  204. }
  205. }
  206. if(event->getDispatcher() == globalFrame->assetBrowser && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::OK_EVENT) {
  207. String newProgramPath = globalFrame->assetBrowser->getFullSelectedAssetPath();
  208. globalFrame->assetBrowser->removeAllHandlersForListener(this);
  209. OSFileEntry entry(newProgramPath, OSFileEntry::TYPE_FILE);
  210. ShaderProgram *newProgram = CoreServices::getInstance()->getMaterialManager()->createProgramFromFile(newProgramPath);
  211. newProgram->reloadOnFileModify = true;
  212. if(newProgram) {
  213. newProgram->setResourceName(entry.name);
  214. newProgram->setResourcePath(newProgramPath);
  215. CoreServices::getInstance()->getResourceManager()->addResource(newProgram);
  216. }
  217. if(choosingVertexProgram) {
  218. currentShader->setVertexProgram(newProgram);
  219. } else {
  220. currentShader->setFragmentProgram(newProgram);
  221. }
  222. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  223. globalFrame->hideModal();
  224. reloadPrograms();
  225. }
  226. }
  227. void ShaderEditorPane::reloadPrograms() {
  228. vertexProgramProp->comboEntry->clearItems();
  229. fragmentProgramProp->comboEntry->clearItems();
  230. vertexProgramProp->comboEntry->addComboItem("Custom...", NULL);
  231. fragmentProgramProp->comboEntry->addComboItem("Custom...", NULL);
  232. std::vector<Resource*> programs = CoreServices::getInstance()->getResourceManager()->getResources(Resource::RESOURCE_PROGRAM);
  233. for(int i=0; i < programs.size(); i++) {
  234. ShaderProgram* program = (ShaderProgram*) programs[i];
  235. if(program->type == ShaderProgram::TYPE_VERT) {
  236. vertexProgramProp->comboEntry->addComboItem(program->getResourceName(), (void*)program);
  237. if(program == currentShader->vp) {
  238. vertexProgramProp->comboEntry->setSelectedIndex(vertexProgramProp->comboEntry->getNumItems()-1);
  239. }
  240. } else if(program->type == ShaderProgram::TYPE_FRAG) {
  241. fragmentProgramProp->comboEntry->addComboItem(program->getResourceName(), (void*)program);
  242. if(program == currentShader->fp) {
  243. fragmentProgramProp->comboEntry->setSelectedIndex(fragmentProgramProp->comboEntry->getNumItems()-1);
  244. }
  245. }
  246. }
  247. }
  248. void ShaderEditorPane::setShader(Shader *shader) {
  249. changingShader = true;
  250. currentShader = shader;
  251. reloadPrograms();
  252. nameProp->set(shader->getName());
  253. for(int i=0; i < vertexProgramProp->comboEntry->getNumItems(); i++) {
  254. ShaderProgram* program = (ShaderProgram*) vertexProgramProp->comboEntry->getItemAtIndex(i)->data;
  255. if(program == shader->vp) {
  256. vertexProgramProp->comboEntry->setSelectedIndex(i);
  257. }
  258. }
  259. for(int i=0; i < fragmentProgramProp->comboEntry->getNumItems(); i++) {
  260. ShaderProgram* program = (ShaderProgram*) fragmentProgramProp->comboEntry->getItemAtIndex(i)->data;
  261. if(program == shader->fp) {
  262. fragmentProgramProp->comboEntry->setSelectedIndex(i);
  263. }
  264. }
  265. screenShaderProp->set(shader->screenShader);
  266. areaLightsProp->set(shader->numAreaLights);
  267. spotLightsProp->set(shader->numSpotLights);
  268. enabled = true;
  269. changingShader = false;
  270. }
  271. void ShaderEditorPane::Resize(Number width, Number height) {
  272. headerBg->setShapeSize(width, 30);
  273. propList->Resize(370, height);
  274. propList->updateProps();
  275. }
  276. MaterialPreviewBox::MaterialPreviewBox() : UIElement() {
  277. currentMaterial = NULL;
  278. previewScene = new Scene(true);
  279. renderTexture = new SceneRenderTexture(previewScene, previewScene->getDefaultCamera(), 512, 512);
  280. ScenePrimitive *previewBg = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 15.0, 15.0, 15.0);
  281. previewBg->Yaw(45.0);
  282. previewBg->backfaceCulled = false;
  283. Material *bgMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("MaterialEditorBg", "Unlit");
  284. previewBg->setMaterial(bgMaterial);
  285. Texture *tex = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile("Images/material_grid.png");
  286. if(previewBg->getLocalShaderOptions()) {
  287. previewBg->getLocalShaderOptions()->addTexture("diffuse", tex);
  288. }
  289. previewScene->addChild(previewBg);
  290. previewScene->clearColor.setColor(0.1, 0.1, 0.1, 0.0);
  291. previewScene->ambientColor.setColor(0.2, 0.2, 0.2, 1.0);
  292. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_TORUS, 3.0, 1.2, 26, 16);
  293. previewScene->addChild(previewPrimitive);
  294. shapePrimitives.push_back(previewPrimitive);
  295. previewPrimitive->getMesh()->calculateTangents();
  296. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_SPHERE, 3.0, 16, 16);
  297. previewScene->addChild(previewPrimitive);
  298. shapePrimitives.push_back(previewPrimitive);
  299. previewPrimitive->getMesh()->calculateTangents();
  300. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_BOX, 4.0, 4.0, 4.0);
  301. previewPrimitive->Yaw(45.0);
  302. previewPrimitive->getMesh()->calculateNormals(false);
  303. previewPrimitive->getMesh()->calculateTangents();
  304. previewScene->addChild(previewPrimitive);
  305. shapePrimitives.push_back(previewPrimitive);
  306. previewPrimitive = new ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 6.0, 6.0);
  307. previewPrimitive->billboardMode = true;
  308. previewScene->addChild(previewPrimitive);
  309. shapePrimitives.push_back(previewPrimitive);
  310. previewPrimitive->getMesh()->calculateTangents();
  311. mainLight = new SceneLight(SceneLight::AREA_LIGHT, previewScene, 290.0);
  312. mainLight->setPosition(-10,10,10);
  313. previewScene->addLight(mainLight);
  314. secondLight = new SceneLight(SceneLight::AREA_LIGHT, previewScene, 250.0);
  315. secondLight->setPosition(10,-10,10);
  316. previewScene->addLight(secondLight);
  317. previewScene->getDefaultCamera()->setPosition(0,7,9);
  318. previewScene->getDefaultCamera()->lookAt(Vector3());
  319. previewBase = new ScreenEntity();
  320. previewBase->processInputEvents = true;
  321. previewBase->setPosition(0, 0);
  322. addChild(previewBase);
  323. previewShape = new ScreenShape(ScreenShape::SHAPE_RECT, 256, 256);
  324. previewShape->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  325. previewShape->setTexture(renderTexture->getTargetTexture());
  326. previewShape->setPosition(20,40);
  327. previewShape->strokeEnabled = true;
  328. previewShape->strokeColor = Color(1.0, 1.0, 1.0, 0.2);
  329. previewShape->setStrokeWidth(1.0);
  330. previewBase->addChild(previewShape);
  331. shapeSelector = new ScreenImage("Images/small_selector.png");
  332. previewBase->addChild(shapeSelector);
  333. shapeSelector->color.a = 0.4;
  334. shapeSwitches.push_back(new UIImageButton("Images/torus_icon.png"));
  335. shapeSwitches.push_back(new UIImageButton("Images/sphere_icon.png"));
  336. shapeSwitches.push_back(new UIImageButton("Images/box_icon.png"));
  337. shapeSwitches.push_back(new UIImageButton("Images/plane_icon.png"));
  338. for(int i=0; i < shapeSwitches.size(); i++) {
  339. previewBase->addChild(shapeSwitches[i]);
  340. shapeSwitches[i]->setPosition(105 + (25 * i), 300);
  341. shapeSwitches[i]->addEventListener(this, UIEvent::CLICK_EVENT);
  342. }
  343. showPrimitive(0);
  344. }
  345. void MaterialPreviewBox::clearMaterial() {
  346. previewPrimitive->clearMaterial();
  347. }
  348. MaterialPreviewBox::~MaterialPreviewBox() {
  349. }
  350. void MaterialPreviewBox::setMaterial(Material *material) {
  351. currentMaterial = material;
  352. previewPrimitive->setMaterial(material);
  353. }
  354. void MaterialPreviewBox::showPrimitive(unsigned int index) {
  355. for(int i=0; i < shapePrimitives.size(); i++) {
  356. shapePrimitives[i]->visible = false;
  357. }
  358. shapePrimitives[index]->visible = true;
  359. shapeSelector->setPosition(105 - 2 + (25 * index), 298);
  360. if(currentMaterial) {
  361. shapePrimitives[index]->setMaterial(currentMaterial);
  362. }
  363. previewPrimitive = shapePrimitives[index];
  364. }
  365. void MaterialPreviewBox::handleEvent(Event *event) {
  366. for(int i=0; i < shapeSwitches.size(); i++) {
  367. if(event->getDispatcher() == shapeSwitches[i]) {
  368. if(event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  369. showPrimitive(i);
  370. }
  371. }
  372. }
  373. }
  374. MaterialEditorPane::MaterialEditorPane() : UIElement() {
  375. changingMaterial = false;
  376. headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
  377. addChild(headerBg);
  378. headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  379. headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
  380. propList = new PropList("MATERIAL EDITOR");
  381. addChild(propList);
  382. propList->setPosition(0, 0);
  383. PropSheet *baseProps = new PropSheet("MATERIAL SETTINGS", "");
  384. propList->addPropSheet(baseProps);
  385. nameProp = new StringProp("Name");
  386. baseProps->addProp(nameProp);
  387. nameProp->addEventListener(this, Event::CHANGE_EVENT);
  388. shaderProp = new ComboProp("Shader");
  389. baseProps->addProp(shaderProp);
  390. shaderProp->addEventListener(this, Event::CHANGE_EVENT);
  391. blendModeProp = new ComboProp("Blend mode");
  392. baseProps->addProp(blendModeProp);
  393. blendModeProp->addEventListener(this, Event::CHANGE_EVENT);
  394. blendModeProp->comboEntry->addComboItem("Normal");
  395. blendModeProp->comboEntry->addComboItem("Lighten");
  396. blendModeProp->comboEntry->addComboItem("Color");
  397. blendModeProp->comboEntry->addComboItem("Premultiplied");
  398. blendModeProp->comboEntry->addComboItem("Multiply");
  399. baseProps->propHeight = 130;
  400. shaderTextureSheet = new ShaderTexturesSheet();
  401. propList->addPropSheet(shaderTextureSheet);
  402. shaderTextureSheet->addEventListener(this, Event::CHANGE_EVENT);
  403. shaderOptionsSheet = new ShaderOptionsSheet("SHADER OPTIONS", "shader_options");
  404. propList->addPropSheet(shaderOptionsSheet);
  405. shaderOptionsSheet->addEventListener(this, Event::CHANGE_EVENT);
  406. propList->updateProps();
  407. materialPreview = new MaterialPreviewBox();
  408. addChild(materialPreview);
  409. materialPreview->setPosition(400, 0);
  410. Config *conf = CoreServices::getInstance()->getConfig();
  411. String fontName = conf->getStringValue("Polycode", "uiDefaultFontName");
  412. currentMaterial = NULL;
  413. reloadShaders();
  414. enabled = false;
  415. }
  416. void MaterialEditorPane::reloadShaders() {
  417. shaderProp->comboEntry->clearItems();
  418. MaterialManager *materialManager = CoreServices::getInstance()->getMaterialManager();
  419. for(int i=0; i < materialManager->getNumShaders(); i++) {
  420. if(!materialManager->getShaderByIndex(i)->screenShader) {
  421. shaderProp->comboEntry->addComboItem(materialManager->getShaderByIndex(i)->getName(), (void*)materialManager->getShaderByIndex(i));
  422. }
  423. }
  424. }
  425. void MaterialEditorPane::Resize(Number width, Number height) {
  426. headerBg->setShapeSize(width, 30);
  427. propList->Resize(370, height);
  428. propList->updateProps();
  429. }
  430. void MaterialEditorPane::handleEvent(Event *event) {
  431. if(event->getDispatcher() == currentMaterial) {
  432. shaderTextureSheet->setShader(currentMaterial->getShader(0), currentMaterial);
  433. shaderOptionsSheet->setShader(currentMaterial->getShader(0), currentMaterial);
  434. }
  435. if(event->getDispatcher() == shaderTextureSheet || event->getDispatcher() == shaderOptionsSheet) {
  436. if(!changingMaterial) {
  437. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  438. }
  439. } else if(event->getDispatcher() == blendModeProp) {
  440. currentMaterial->blendingMode = blendModeProp->get();
  441. if(!changingMaterial) {
  442. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  443. }
  444. } else if(event->getDispatcher() == nameProp) {
  445. currentMaterial->setName(nameProp->get());
  446. if(!changingMaterial) {
  447. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  448. }
  449. } else if(event->getDispatcher() == shaderProp) {
  450. Shader *selectedShader = (Shader*)shaderProp->comboEntry->getSelectedItem()->data;
  451. if(selectedShader) {
  452. if(currentMaterial->getShader(0) != selectedShader) {
  453. currentMaterial->clearShaders();
  454. materialPreview->clearMaterial();
  455. ShaderBinding *newShaderBinding = selectedShader->createBinding();
  456. currentMaterial->addShader(selectedShader, newShaderBinding);
  457. materialPreview->setMaterial(currentMaterial);
  458. }
  459. shaderTextureSheet->setShader(selectedShader, currentMaterial);
  460. shaderOptionsSheet->setShader(selectedShader, currentMaterial);
  461. }
  462. if(!changingMaterial) {
  463. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  464. }
  465. }
  466. }
  467. void MaterialEditorPane::setMaterial(Material *material) {
  468. changingMaterial = true;
  469. if(currentMaterial) {
  470. currentMaterial->removeAllHandlersForListener(this);
  471. }
  472. currentMaterial = material;
  473. materialPreview->setMaterial(material);
  474. material->addEventListener(this, Event::RESOURCE_RELOAD_EVENT);
  475. reloadShaders();
  476. if(!currentMaterial)
  477. return;
  478. blendModeProp->set(currentMaterial->blendingMode);
  479. if(currentMaterial->getShader(0)) {
  480. for(int i=0; i < shaderProp->comboEntry->getNumItems(); i++) {
  481. Shader *shader = (Shader*)shaderProp->comboEntry->getItemAtIndex(i)->data;
  482. if(shader) {
  483. if(currentMaterial->getShader(0)->getName() == shader->getName()) {
  484. shaderProp->set(i);
  485. shaderProp->dispatchEvent(new Event(), Event::CHANGE_EVENT);
  486. break;
  487. }
  488. }
  489. }
  490. } else {
  491. shaderProp->set(0);
  492. shaderProp->dispatchEvent(new Event(), Event::CHANGE_EVENT);
  493. }
  494. nameProp->set(currentMaterial->getName());
  495. enabled = true;
  496. changingMaterial = false;
  497. }
  498. MaterialEditorPane::~MaterialEditorPane() {
  499. }
  500. MaterialMainWindow::MaterialMainWindow() : UIElement() {
  501. materialPane = new MaterialEditorPane();
  502. shaderPane = new ShaderEditorPane();
  503. cubemapPane = new CubemapEditorPane();
  504. addChild(materialPane);
  505. addChild(shaderPane);
  506. addChild(cubemapPane);
  507. enableScissor = true;
  508. }
  509. void MaterialMainWindow::Resize(Number width, Number height) {
  510. Vector2 pos = getScreenPosition();
  511. scissorBox.setRect(pos.x,pos.y,width, height);
  512. materialPane->Resize(width, height);
  513. shaderPane->Resize(width, height);
  514. cubemapPane->Resize(width, height);
  515. }
  516. MaterialBrowser::MaterialBrowser() : UIElement() {
  517. treeContainer = new UITreeContainer("boxIcon.png", L"Material Library", 200, 555);
  518. treeContainer->getRootNode()->toggleCollapsed();
  519. treeContainer->getRootNode()->addEventListener(this, UITreeEvent::SELECTED_EVENT);
  520. treeContainer->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
  521. shadersNode = treeContainer->getRootNode()->addTreeChild("Images/shader_icon.png", "Shaders", NULL);
  522. materialsNode = treeContainer->getRootNode()->addTreeChild("Images/material_icon.png", "Materials", NULL);
  523. cubemapsNode = treeContainer->getRootNode()->addTreeChild("Images/cubemap_icon.png", "Cubemaps", NULL);
  524. postEffectsNode = treeContainer->getRootNode()->addTreeChild("folder.png", "Post Effects", NULL);
  525. addChild(treeContainer);
  526. selectedData = NULL;
  527. headerBg = new ScreenShape(ScreenShape::SHAPE_RECT,10,10);
  528. addChild(headerBg);
  529. headerBg->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
  530. headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
  531. newShaderButton = new UIImageButton("Images/new_shader.png");
  532. addChild(newShaderButton);
  533. newShaderButton->setPosition(5,4);
  534. newMaterialButton = new UIImageButton("Images/new_material.png");
  535. addChild(newMaterialButton);
  536. newMaterialButton->setPosition(32,4);
  537. newCubemapButton = new UIImageButton("Images/new_cubemap.png");
  538. addChild(newCubemapButton);
  539. newCubemapButton->setPosition(59,4);
  540. selectedNode = NULL;
  541. }
  542. void MaterialBrowser::handleEvent(Event *event) {
  543. if(event->getDispatcher() == treeContainer->getRootNode()) {
  544. if(event->getEventCode() == UITreeEvent::SELECTED_EVENT){
  545. selectedNode = treeContainer->getRootNode()->getSelectedNode();
  546. MaterialBrowserData *data = (MaterialBrowserData *)selectedNode->getUserData();
  547. selectedData = data;
  548. dispatchEvent(new Event(), Event::CHANGE_EVENT);
  549. }
  550. }
  551. ScreenEntity::handleEvent(event);
  552. }
  553. UITree *MaterialBrowser::addMaterial(Material *material) {
  554. MaterialBrowserData *data = new MaterialBrowserData();
  555. data->material = material;
  556. return materialsNode->addTreeChild("material_icon.png", material->getName(), (void*)data);
  557. }
  558. UITree *MaterialBrowser::addShader(Shader *shader) {
  559. MaterialBrowserData *data = new MaterialBrowserData();
  560. data->shader = shader;
  561. return shadersNode->addTreeChild("shader_icon.png", shader->getName(), (void*)data);
  562. }
  563. UITree *MaterialBrowser::addCubemap(Cubemap *cubemap) {
  564. MaterialBrowserData *data = new MaterialBrowserData();
  565. data->cubemap = cubemap;
  566. return cubemapsNode->addTreeChild("cubemap_icon.png", cubemap->getResourceName(), (void*)data);
  567. }
  568. MaterialBrowser::~MaterialBrowser() {
  569. }
  570. void MaterialBrowser::Resize(Number width, Number height) {
  571. treeContainer->Resize(width, height-30);
  572. treeContainer->setPosition(0, 30);
  573. headerBg->setShapeSize(width, 30);
  574. }
  575. PolycodeMaterialEditor::PolycodeMaterialEditor() : PolycodeEditor(true){
  576. selectedMaterialNode = NULL;
  577. }
  578. PolycodeMaterialEditor::~PolycodeMaterialEditor() {
  579. }
  580. bool PolycodeMaterialEditor::openFile(OSFileEntry filePath) {
  581. mainSizer = new UIHSizer(100,100,200,false);
  582. addChild(mainSizer);
  583. materialBrowser = new MaterialBrowser();
  584. mainSizer->addRightChild(materialBrowser);
  585. materialBrowser->addEventListener(this, Event::CHANGE_EVENT);
  586. shaders = CoreServices::getInstance()->getMaterialManager()->loadShadersFromFile(filePath.fullPath);
  587. for(int i=0; i < shaders.size(); i++) {
  588. materialBrowser->addShader(shaders[i]);
  589. CoreServices::getInstance()->getMaterialManager()->addShader(shaders[i]);
  590. CoreServices::getInstance()->getResourceManager()->addResource(shaders[i]);
  591. }
  592. cubemaps = CoreServices::getInstance()->getMaterialManager()->loadCubemapsFromFile(filePath.fullPath);
  593. for(int i=0; i < cubemaps.size(); i++) {
  594. materialBrowser->addCubemap(cubemaps[i]);
  595. CoreServices::getInstance()->getResourceManager()->addResource(cubemaps[i]);
  596. }
  597. materials = CoreServices::getInstance()->getMaterialManager()->loadMaterialsFromFile(filePath.fullPath);
  598. for(int i=0; i < materials.size(); i++) {
  599. materialBrowser->addMaterial(materials[i]);
  600. }
  601. mainWindow = new MaterialMainWindow();
  602. mainSizer->addLeftChild(mainWindow);
  603. mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
  604. mainWindow->shaderPane->addEventListener(this, Event::CHANGE_EVENT);
  605. mainWindow->cubemapPane->addEventListener(this, Event::CHANGE_EVENT);
  606. mainWindow->shaderPane->parentProject = parentProject;
  607. materialBrowser->newMaterialButton->addEventListener(this, UIEvent::CLICK_EVENT);
  608. materialBrowser->newShaderButton->addEventListener(this, UIEvent::CLICK_EVENT);
  609. materialBrowser->newCubemapButton->addEventListener(this, UIEvent::CLICK_EVENT);
  610. mainWindow->materialPane->addEventListener(this, Event::CHANGE_EVENT);
  611. PolycodeEditor::openFile(filePath);
  612. return true;
  613. }
  614. String PolycodeMaterialEditor::createStringValue(unsigned int type, void *value) {
  615. String retString;
  616. switch(type) {
  617. case ProgramParam::PARAM_NUMBER:
  618. retString = String::NumberToString(*((Number*)value));
  619. break;
  620. case ProgramParam::PARAM_COLOR:
  621. {
  622. Color color = *((Color*)value);
  623. retString = String::NumberToString(color.r) + " " + String::NumberToString(color.g) + " " + String::NumberToString(color.b) + " " + String::NumberToString(color.a);
  624. }
  625. break;
  626. case ProgramParam::PARAM_VECTOR2:
  627. {
  628. Vector2 vec = *((Vector2*)value);
  629. retString = String::NumberToString(vec.x) + " " + String::NumberToString(vec.y);
  630. }
  631. break;
  632. case ProgramParam::PARAM_VECTOR3:
  633. {
  634. Vector3 vec = *((Vector3*)value);
  635. retString = String::NumberToString(vec.x) + " " + String::NumberToString(vec.y) + " " + String::NumberToString(vec.z);
  636. }
  637. break;
  638. }
  639. return retString;
  640. }
  641. void PolycodeMaterialEditor::saveFile() {
  642. Object fileData;
  643. fileData.root.name = "polycode_material_library";
  644. ObjectEntry *shadersEntry = fileData.root.addChild("shaders");
  645. for(int i=0; i < shaders.size(); i++) {
  646. ObjectEntry *shaderEntry = shadersEntry->addChild("shader");
  647. shaderEntry->addChild("type", String("glsl"));
  648. shaderEntry->addChild("name", shaders[i]->getName());
  649. shaderEntry->addChild("numAreaLights", shaders[i]->numAreaLights);
  650. shaderEntry->addChild("numSpotLights", shaders[i]->numSpotLights);
  651. shaderEntry->addChild("screen", shaders[i]->screenShader);
  652. ObjectEntry *vpEntry = shaderEntry->addChild("vp");
  653. String sourcePath = shaders[i]->vp->getResourcePath();
  654. sourcePath = sourcePath.replace(parentProject->getRootFolder()+"/", "");
  655. vpEntry->addChild("source", sourcePath);
  656. ObjectEntry *fpEntry = shaderEntry->addChild("fp");
  657. sourcePath = shaders[i]->fp->getResourcePath();
  658. sourcePath = sourcePath.replace(parentProject->getRootFolder()+"/", "");
  659. fpEntry->addChild("source", sourcePath);
  660. }
  661. ObjectEntry *cubemapsEntry = fileData.root.addChild("cubemaps");
  662. for(int i=0; i < cubemaps.size(); i++) {
  663. ObjectEntry *cubemapEntry = cubemapsEntry->addChild("cubemap");
  664. cubemapEntry->addChild("name", cubemaps[i]->getResourceName());
  665. cubemapEntry->addChild("xPos", cubemaps[i]->getTexture(Cubemap::CUBEMAP_XPOS)->getResourcePath());
  666. cubemapEntry->addChild("xNeg", cubemaps[i]->getTexture(Cubemap::CUBEMAP_XNEG)->getResourcePath());
  667. cubemapEntry->addChild("yPos", cubemaps[i]->getTexture(Cubemap::CUBEMAP_YPOS)->getResourcePath());
  668. cubemapEntry->addChild("yNeg", cubemaps[i]->getTexture(Cubemap::CUBEMAP_YNEG)->getResourcePath());
  669. cubemapEntry->addChild("zPos", cubemaps[i]->getTexture(Cubemap::CUBEMAP_ZPOS)->getResourcePath());
  670. cubemapEntry->addChild("zNeg", cubemaps[i]->getTexture(Cubemap::CUBEMAP_ZNEG)->getResourcePath());
  671. }
  672. ObjectEntry *materialsEntry = fileData.root.addChild("materials");
  673. for(int i=0; i < materials.size(); i++) {
  674. Material *material = materials[i];
  675. ObjectEntry *materialEntry = materialsEntry->addChild("material");
  676. materialEntry->addChild("name", material->getName());
  677. materialEntry->addChild("blendingMode", material->blendingMode);
  678. if(material->getShader(0) && material->getShaderBinding(0)) {
  679. Shader *shader = material->getShader(0);
  680. ObjectEntry *shaderEntry = materialEntry->addChild("shader");
  681. shaderEntry->addChild("name", shader->getName());
  682. ObjectEntry *texturesEntry = shaderEntry->addChild("textures");
  683. ShaderBinding *shaderBinding = material->getShaderBinding(0);
  684. for(int j=0; j < shader->expectedTextures.size(); j++) {
  685. Texture *texture = shaderBinding->getTexture(shader->expectedTextures[j]);
  686. if(texture) {
  687. String texturePath = texture->getResourcePath();
  688. texturePath = texturePath.replace(parentProject->getRootFolder()+"/", "");
  689. ObjectEntry *textureEntry = texturesEntry->addChild("texture", texturePath);
  690. textureEntry->addChild("name", shader->expectedTextures[j]);
  691. }
  692. }
  693. for(int j=0; j < shader->expectedCubemaps.size(); j++) {
  694. Cubemap *cubemap = shaderBinding->getCubemap(shader->expectedCubemaps[j]);
  695. if(cubemap) {
  696. String cubemapName = cubemap->getResourceName();
  697. ObjectEntry *cubemapEntry = texturesEntry->addChild("cubemap", cubemapName);
  698. cubemapEntry->addChild("name", shader->expectedCubemaps[j]);
  699. }
  700. }
  701. if(shader->expectedParams.size() > 0 || shader->expectedParams.size() > 0) {
  702. ObjectEntry *paramsEntry = shaderEntry->addChild("params");
  703. for(int j=0; j < shader->expectedParams.size(); j++) {
  704. if(shaderBinding->getLocalParamByName(shader->expectedParams[j].name)) {
  705. ObjectEntry *paramEntry = paramsEntry->addChild("param");
  706. paramEntry->addChild("name", shader->expectedParams[j].name);
  707. paramEntry->addChild("value", createStringValue(shader->expectedParams[j].type, shaderBinding->getLocalParamByName(shader->expectedParams[j].name)->data));
  708. }
  709. }
  710. }
  711. }
  712. }
  713. fileData.saveToXML(filePath);
  714. setHasChanges(false);
  715. }
  716. void PolycodeMaterialEditor::handleEvent(Event *event) {
  717. if(event->getDispatcher() == mainWindow->materialPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  718. if(selectedMaterialNode && mainWindow->materialPane->currentMaterial) {
  719. selectedMaterialNode->setLabelText(mainWindow->materialPane->currentMaterial->getName());
  720. }
  721. setHasChanges(true);
  722. }
  723. if(event->getDispatcher() == mainWindow->shaderPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  724. if(selectedMaterialNode && mainWindow->shaderPane->currentShader) {
  725. selectedMaterialNode->setLabelText(mainWindow->shaderPane->currentShader->getName());
  726. }
  727. setHasChanges(true);
  728. }
  729. if(event->getDispatcher() == mainWindow->cubemapPane && event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  730. if(selectedMaterialNode && mainWindow->cubemapPane->currentCubemap) {
  731. selectedMaterialNode->setLabelText(mainWindow->cubemapPane->currentCubemap->getResourceName());
  732. }
  733. setHasChanges(true);
  734. }
  735. if(event->getDispatcher() == materialBrowser->newMaterialButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  736. Material *newMaterial = CoreServices::getInstance()->getMaterialManager()->createMaterial("Untitled", "DefaultShader");
  737. materialBrowser->addMaterial(newMaterial)->setSelected();
  738. materials.push_back(newMaterial);
  739. setHasChanges(true);
  740. }
  741. if(event->getDispatcher() == materialBrowser->newShaderButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  742. Shader *newShader = CoreServices::getInstance()->getMaterialManager()->createShader("glsl", "Untitled", "Unlit.vert", "Unlit.frag", false);
  743. if(newShader) {
  744. materialBrowser->addShader(newShader);
  745. shaders.push_back(newShader);
  746. CoreServices::getInstance()->getMaterialManager()->addShader(newShader);
  747. setHasChanges(true);
  748. } else {
  749. printf("Error creating shader!\n");
  750. }
  751. }
  752. if(event->getDispatcher() == materialBrowser->newCubemapButton && event->getEventType() == "UIEvent" && event->getEventCode() == UIEvent::CLICK_EVENT) {
  753. Cubemap *cubemap = CoreServices::getInstance()->getRenderer()->createCubemap(
  754. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  755. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  756. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  757. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  758. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"),
  759. (Texture*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_TEXTURE, "default.png"));
  760. cubemap->setResourceName("Cubemap"+String::IntToString(cubemaps.size()));
  761. cubemaps.push_back(cubemap);
  762. materialBrowser->addCubemap(cubemap);
  763. setHasChanges(true);
  764. CoreServices::getInstance()->getResourceManager()->addResource(cubemap);
  765. }
  766. if(event->getDispatcher() == materialBrowser) {
  767. if(event->getEventType() == "" && event->getEventCode() == Event::CHANGE_EVENT) {
  768. if(materialBrowser->selectedData) {
  769. mainWindow->materialPane->enabled = false;
  770. mainWindow->shaderPane->enabled = false;
  771. mainWindow->cubemapPane->enabled = false;
  772. if(materialBrowser->selectedData->material) {
  773. selectedMaterialNode = materialBrowser->selectedNode;
  774. mainWindow->materialPane->setMaterial(materialBrowser->selectedData->material);
  775. } else if(materialBrowser->selectedData->shader) {
  776. selectedMaterialNode = materialBrowser->selectedNode;
  777. mainWindow->shaderPane->setShader(materialBrowser->selectedData->shader);
  778. } else if(materialBrowser->selectedData->cubemap) {
  779. selectedMaterialNode = materialBrowser->selectedNode;
  780. mainWindow->cubemapPane->setCubemap(materialBrowser->selectedData->cubemap);
  781. }
  782. }
  783. }
  784. }
  785. }
  786. void PolycodeMaterialEditor::Resize(int x, int y) {
  787. mainSizer->Resize(x,y);
  788. PolycodeEditor::Resize(x,y);
  789. }