OpenGLExampleBrowser.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. #include "OpenGLExampleBrowser.h"
  2. #include "LinearMath/btQuickprof.h"
  3. #include "../OpenGLWindow/OpenGLInclude.h"
  4. #include "../OpenGLWindow/SimpleOpenGL2App.h"
  5. #ifndef NO_OPENGL3
  6. #include "../OpenGLWindow/SimpleOpenGL3App.h"
  7. #endif
  8. #include "../CommonInterfaces/CommonRenderInterface.h"
  9. #ifdef __APPLE__
  10. #include "../OpenGLWindow/MacOpenGLWindow.h"
  11. #else
  12. #ifdef _WIN32
  13. #include "../OpenGLWindow/Win32OpenGLWindow.h"
  14. #else
  15. //let's cross the fingers it is Linux/X11
  16. #include "../OpenGLWindow/X11OpenGLWindow.h"
  17. #endif //_WIN32
  18. #endif//__APPLE__
  19. #include "../ThirdPartyLibs/Gwen/Renderers/OpenGL_DebugFont.h"
  20. #include "Bullet3Common/b3Vector3.h"
  21. #include "assert.h"
  22. #include <stdio.h>
  23. #include "GwenGUISupport/gwenInternalData.h"
  24. #include "GwenGUISupport/gwenUserInterface.h"
  25. #include "../Utils/b3Clock.h"
  26. #include "GwenGUISupport/GwenParameterInterface.h"
  27. #include "GwenGUISupport/GwenProfileWindow.h"
  28. #include "GwenGUISupport/GwenTextureWindow.h"
  29. #include "GwenGUISupport/GraphingTexture.h"
  30. #include "../CommonInterfaces/Common2dCanvasInterface.h"
  31. #include "../CommonInterfaces/CommonExampleInterface.h"
  32. #include "Bullet3Common/b3CommandLineArgs.h"
  33. #include "../OpenGLWindow/SimpleCamera.h"
  34. #include "../OpenGLWindow/SimpleOpenGL2Renderer.h"
  35. #include "ExampleEntries.h"
  36. #include "OpenGLGuiHelper.h"
  37. #include "Bullet3Common/b3FileUtils.h"
  38. #include "LinearMath/btIDebugDraw.h"
  39. //quick test for file import, @todo(erwincoumans) make it more general and add other file formats
  40. #include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
  41. #include "../Importers/ImportBullet/SerializeSetup.h"
  42. #include "Bullet3Common/b3HashMap.h"
  43. struct GL3TexLoader : public MyTextureLoader
  44. {
  45. b3HashMap<b3HashString, GLint> m_hashMap;
  46. virtual void LoadTexture(Gwen::Texture* pTexture)
  47. {
  48. Gwen::String namestr = pTexture->name.Get();
  49. const char* n = namestr.c_str();
  50. GLint* texIdPtr = m_hashMap[n];
  51. if (texIdPtr)
  52. {
  53. pTexture->m_intData = *texIdPtr;
  54. }
  55. }
  56. virtual void FreeTexture(Gwen::Texture* pTexture)
  57. {
  58. }
  59. };
  60. struct OpenGLExampleBrowserInternalData
  61. {
  62. Gwen::Renderer::Base* m_gwenRenderer;
  63. CommonGraphicsApp* m_app;
  64. // MyProfileWindow* m_profWindow;
  65. btAlignedObjectArray<Gwen::Controls::TreeNode*> m_nodes;
  66. GwenUserInterface* m_gui;
  67. GL3TexLoader* m_myTexLoader;
  68. struct MyMenuItemHander* m_handler2;
  69. btAlignedObjectArray<MyMenuItemHander*> m_handlers;
  70. OpenGLExampleBrowserInternalData()
  71. : m_gwenRenderer(0),
  72. m_app(0),
  73. // m_profWindow(0),
  74. m_gui(0),
  75. m_myTexLoader(0),
  76. m_handler2(0)
  77. {
  78. }
  79. };
  80. static CommonGraphicsApp* s_app=0;
  81. static CommonWindowInterface* s_window = 0;
  82. static CommonParameterInterface* s_parameterInterface=0;
  83. static CommonRenderInterface* s_instancingRenderer=0;
  84. static OpenGLGuiHelper* s_guiHelper=0;
  85. //static MyProfileWindow* s_profWindow =0;
  86. static SharedMemoryInterface* sSharedMem = 0;
  87. #define DEMO_SELECTION_COMBOBOX 13
  88. const char* startFileName = "0_Bullet3Demo.txt";
  89. char staticPngFileName[1024];
  90. //static GwenUserInterface* gui = 0;
  91. static GwenUserInterface* gui2 = 0;
  92. static int sCurrentDemoIndex = -1;
  93. static int sCurrentHightlighted = 0;
  94. static CommonExampleInterface* sCurrentDemo = 0;
  95. static b3AlignedObjectArray<const char*> allNames;
  96. static float gFixedTimeStep = 0;
  97. bool gAllowRetina = true;
  98. bool gDisableDemoSelection = false;
  99. static class ExampleEntries* gAllExamples=0;
  100. bool sUseOpenGL2 = false;
  101. bool drawGUI=true;
  102. #ifndef USE_OPENGL3
  103. extern bool useShadowMap;
  104. #endif
  105. static bool visualWireframe=false;
  106. static bool renderVisualGeometry=true;
  107. static bool renderGrid = true;
  108. static bool renderGui = true;
  109. static bool enable_experimental_opencl = false;
  110. int gDebugDrawFlags = 0;
  111. static bool pauseSimulation=false;
  112. static bool singleStepSimulation = false;
  113. int midiBaseIndex = 176;
  114. extern bool gDisableDeactivation;
  115. int gSharedMemoryKey=-1;
  116. ///some quick test variable for the OpenCL examples
  117. int gPreferredOpenCLDeviceIndex=-1;
  118. int gPreferredOpenCLPlatformIndex=-1;
  119. int gGpuArraySizeX=15;
  120. int gGpuArraySizeY=15;
  121. int gGpuArraySizeZ=15;
  122. //#include <float.h>
  123. //unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);
  124. void deleteDemo()
  125. {
  126. if (sCurrentDemo)
  127. {
  128. sCurrentDemo->exitPhysics();
  129. s_instancingRenderer->removeAllInstances();
  130. delete sCurrentDemo;
  131. sCurrentDemo=0;
  132. delete s_guiHelper;
  133. s_guiHelper = 0;
  134. }
  135. }
  136. const char* gPngFileName = 0;
  137. int gPngSkipFrames = 0;
  138. b3KeyboardCallback prevKeyboardCallback = 0;
  139. void MyKeyboardCallback(int key, int state)
  140. {
  141. //b3Printf("key=%d, state=%d", key, state);
  142. bool handled = false;
  143. if (gui2 && !handled )
  144. {
  145. handled = gui2->keyboardCallback(key, state);
  146. }
  147. if (!handled && sCurrentDemo)
  148. {
  149. handled = sCurrentDemo->keyboardCallback(key,state);
  150. }
  151. //checkout: is it desired to ignore keys, if the demo already handles them?
  152. //if (handled)
  153. // return;
  154. if (key=='a' && state)
  155. {
  156. gDebugDrawFlags ^= btIDebugDraw::DBG_DrawAabb;
  157. }
  158. if (key=='c' && state)
  159. {
  160. gDebugDrawFlags ^= btIDebugDraw::DBG_DrawContactPoints;
  161. }
  162. if (key == 'd' && state)
  163. {
  164. gDebugDrawFlags ^= btIDebugDraw::DBG_NoDeactivation;
  165. gDisableDeactivation = ((gDebugDrawFlags & btIDebugDraw::DBG_NoDeactivation) != 0);
  166. }
  167. if (key == 'k' && state)
  168. {
  169. gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraints;
  170. }
  171. if (key=='l' && state)
  172. {
  173. gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraintLimits;
  174. }
  175. if (key=='w' && state)
  176. {
  177. visualWireframe=!visualWireframe;
  178. gDebugDrawFlags ^= btIDebugDraw::DBG_DrawWireframe;
  179. }
  180. if (key=='v' && state)
  181. {
  182. renderVisualGeometry = !renderVisualGeometry;
  183. }
  184. if (key=='g' && state)
  185. {
  186. renderGrid = !renderGrid;
  187. renderGui = !renderGui;
  188. }
  189. if (key=='i' && state)
  190. {
  191. pauseSimulation = !pauseSimulation;
  192. }
  193. if (key == 'o' && state)
  194. {
  195. singleStepSimulation = true;
  196. }
  197. #ifndef NO_OPENGL3
  198. if (key=='s' && state)
  199. {
  200. useShadowMap=!useShadowMap;
  201. }
  202. #endif
  203. if (key==B3G_F1)
  204. {
  205. static int count=0;
  206. if (state)
  207. {
  208. b3Printf("F1 pressed %d", count++);
  209. if (gPngFileName)
  210. {
  211. b3Printf("disable image dump");
  212. gPngFileName=0;
  213. } else
  214. {
  215. gPngFileName = gAllExamples->getExampleName(sCurrentDemoIndex);
  216. b3Printf("enable image dump %s",gPngFileName);
  217. }
  218. } else
  219. {
  220. b3Printf("F1 released %d",count++);
  221. }
  222. }
  223. if (key==B3G_ESCAPE && s_window)
  224. {
  225. s_window->setRequestExit();
  226. }
  227. if (prevKeyboardCallback)
  228. prevKeyboardCallback(key,state);
  229. }
  230. b3MouseMoveCallback prevMouseMoveCallback = 0;
  231. static void MyMouseMoveCallback( float x, float y)
  232. {
  233. bool handled = false;
  234. if (sCurrentDemo)
  235. handled = sCurrentDemo->mouseMoveCallback(x,y);
  236. if (!handled && gui2)
  237. handled = gui2->mouseMoveCallback(x,y);
  238. if (!handled)
  239. {
  240. if (prevMouseMoveCallback)
  241. prevMouseMoveCallback(x,y);
  242. }
  243. }
  244. b3MouseButtonCallback prevMouseButtonCallback = 0;
  245. static void MyMouseButtonCallback(int button, int state, float x, float y)
  246. {
  247. bool handled = false;
  248. //try picking first
  249. if (sCurrentDemo)
  250. handled = sCurrentDemo->mouseButtonCallback(button,state,x,y);
  251. if (!handled && gui2)
  252. handled = gui2->mouseButtonCallback(button,state,x,y);
  253. if (!handled)
  254. {
  255. if (prevMouseButtonCallback )
  256. prevMouseButtonCallback (button,state,x,y);
  257. }
  258. // b3DefaultMouseButtonCallback(button,state,x,y);
  259. }
  260. #include <string.h>
  261. struct FileImporterByExtension
  262. {
  263. std::string m_extension;
  264. CommonExampleInterface::CreateFunc* m_createFunc;
  265. };
  266. static btAlignedObjectArray<FileImporterByExtension> gFileImporterByExtension;
  267. void OpenGLExampleBrowser::registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc)
  268. {
  269. FileImporterByExtension fi;
  270. fi.m_extension = extension;
  271. fi.m_createFunc = createFunc;
  272. gFileImporterByExtension.push_back(fi);
  273. }
  274. void openFileDemo(const char* filename)
  275. {
  276. if (sCurrentDemo)
  277. {
  278. sCurrentDemo->exitPhysics();
  279. s_instancingRenderer->removeAllInstances();
  280. delete sCurrentDemo;
  281. sCurrentDemo=0;
  282. delete s_guiHelper;
  283. s_guiHelper = 0;
  284. }
  285. s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
  286. s_parameterInterface->removeAllParameters();
  287. CommonExampleOptions options(s_guiHelper,1);
  288. options.m_fileName = filename;
  289. char fullPath[1024];
  290. sprintf(fullPath, "%s", filename);
  291. b3FileUtils::toLower(fullPath);
  292. for (int i=0;i<gFileImporterByExtension.size();i++)
  293. {
  294. if (strstr(fullPath, gFileImporterByExtension[i].m_extension.c_str()))
  295. {
  296. sCurrentDemo = gFileImporterByExtension[i].m_createFunc(options);
  297. }
  298. }
  299. if (sCurrentDemo)
  300. {
  301. sCurrentDemo->initPhysics();
  302. sCurrentDemo->resetCamera();
  303. }
  304. }
  305. void selectDemo(int demoIndex)
  306. {
  307. bool resetCamera = (sCurrentDemoIndex != demoIndex);
  308. sCurrentDemoIndex = demoIndex;
  309. sCurrentHightlighted = demoIndex;
  310. int numDemos = gAllExamples->getNumRegisteredExamples();
  311. if (demoIndex>numDemos)
  312. {
  313. demoIndex = 0;
  314. }
  315. deleteDemo();
  316. CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex);
  317. if (func)
  318. {
  319. if (s_parameterInterface)
  320. {
  321. s_parameterInterface->removeAllParameters();
  322. }
  323. int option = gAllExamples->getExampleOption(demoIndex);
  324. s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
  325. CommonExampleOptions options(s_guiHelper, option);
  326. options.m_sharedMem = sSharedMem;
  327. sCurrentDemo = (*func)(options);
  328. if (sCurrentDemo)
  329. {
  330. if (gui2)
  331. {
  332. gui2->setStatusBarMessage("Status: OK", false);
  333. }
  334. b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex));
  335. if (gui2)
  336. {
  337. gui2->setExampleDescription(gAllExamples->getExampleDescription(demoIndex));
  338. }
  339. sCurrentDemo->initPhysics();
  340. if(resetCamera)
  341. {
  342. sCurrentDemo->resetCamera();
  343. }
  344. }
  345. }
  346. }
  347. #include <stdio.h>
  348. static void saveCurrentSettings(int currentEntry,const char* startFileName)
  349. {
  350. FILE* f = fopen(startFileName,"w");
  351. if (f)
  352. {
  353. fprintf(f,"--start_demo_name=%s\n", gAllExamples->getExampleName(sCurrentDemoIndex));
  354. fprintf(f,"--mouse_move_multiplier=%f\n", s_app->getMouseMoveMultiplier());
  355. fprintf(f,"--mouse_wheel_multiplier=%f\n", s_app->getMouseWheelMultiplier());
  356. float red,green,blue;
  357. s_app->getBackgroundColor(&red,&green,&blue);
  358. fprintf(f,"--background_color_red= %f\n", red);
  359. fprintf(f,"--background_color_green= %f\n", green);
  360. fprintf(f,"--background_color_blue= %f\n", blue);
  361. fprintf(f,"--fixed_timestep= %f\n", gFixedTimeStep);
  362. if (!gAllowRetina)
  363. {
  364. fprintf(f,"--disable_retina");
  365. }
  366. if (enable_experimental_opencl)
  367. {
  368. fprintf(f,"--enable_experimental_opencl\n");
  369. }
  370. if (sUseOpenGL2 )
  371. {
  372. fprintf(f,"--opengl2\n");
  373. }
  374. fclose(f);
  375. }
  376. };
  377. static void loadCurrentSettings(const char* startFileName, b3CommandLineArgs& args)
  378. {
  379. int currentEntry= 0;
  380. FILE* f = fopen(startFileName,"r");
  381. if (f)
  382. {
  383. char oneline[1024];
  384. char* argv[] = {0,&oneline[0]};
  385. while( fgets (oneline, 1024, f)!=NULL )
  386. {
  387. char *pos;
  388. if ((pos=strchr(oneline, '\n')) != NULL)
  389. *pos = '\0';
  390. args.addArgs(2,argv);
  391. }
  392. fclose(f);
  393. }
  394. };
  395. void MyComboBoxCallback(int comboId, const char* item)
  396. {
  397. //printf("comboId = %d, item = %s\n",comboId, item);
  398. if (comboId==DEMO_SELECTION_COMBOBOX)
  399. {
  400. //find selected item
  401. for (int i=0;i<allNames.size();i++)
  402. {
  403. if (strcmp(item,allNames[i])==0)
  404. {
  405. selectDemo(i);
  406. saveCurrentSettings(sCurrentDemoIndex,startFileName);
  407. break;
  408. }
  409. }
  410. }
  411. }
  412. void MyGuiPrintf(const char* msg)
  413. {
  414. printf("b3Printf: %s\n",msg);
  415. if (!gDisableDemoSelection)
  416. {
  417. gui2->textOutput(msg);
  418. gui2->forceUpdateScrollBars();
  419. }
  420. }
  421. void MyStatusBarPrintf(const char* msg)
  422. {
  423. printf("b3Printf: %s\n", msg);
  424. if (!gDisableDemoSelection)
  425. {
  426. bool isLeft = true;
  427. gui2->setStatusBarMessage(msg,isLeft);
  428. }
  429. }
  430. void MyStatusBarError(const char* msg)
  431. {
  432. printf("Warning: %s\n", msg);
  433. if (!gDisableDemoSelection)
  434. {
  435. bool isLeft = false;
  436. gui2->setStatusBarMessage(msg,isLeft);
  437. gui2->textOutput(msg);
  438. gui2->forceUpdateScrollBars();
  439. }
  440. btAssert(0);
  441. }
  442. struct MyMenuItemHander :public Gwen::Event::Handler
  443. {
  444. int m_buttonId;
  445. MyMenuItemHander( int buttonId)
  446. :m_buttonId(buttonId)
  447. {
  448. }
  449. void onButtonA(Gwen::Controls::Base* pControl)
  450. {
  451. //const Gwen::String& name = pControl->GetName();
  452. Gwen::Controls::TreeNode* node = (Gwen::Controls::TreeNode*)pControl;
  453. // Gwen::Controls::Label* l = node->GetButton();
  454. Gwen::UnicodeString la = node->GetButton()->GetText();// node->GetButton()->GetName();// GetText();
  455. Gwen::String laa = Gwen::Utility::UnicodeToString(la);
  456. // const char* ha = laa.c_str();
  457. //printf("selected %s\n", ha);
  458. //int dep = but->IsDepressed();
  459. //int tog = but->GetToggleState();
  460. // if (m_data->m_toggleButtonCallback)
  461. // (*m_data->m_toggleButtonCallback)(m_buttonId, tog);
  462. }
  463. void onButtonB(Gwen::Controls::Base* pControl)
  464. {
  465. Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
  466. Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
  467. Gwen::String laa = Gwen::Utility::UnicodeToString(la);
  468. //const char* ha = laa.c_str();
  469. if (!gDisableDemoSelection )
  470. {
  471. selectDemo(sCurrentHightlighted);
  472. saveCurrentSettings(sCurrentDemoIndex, startFileName);
  473. }
  474. }
  475. void onButtonC(Gwen::Controls::Base* pControl)
  476. {
  477. /*Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
  478. Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
  479. Gwen::String laa = Gwen::Utility::UnicodeToString(la);
  480. const char* ha = laa.c_str();
  481. printf("onButtonC ! %s\n", ha);
  482. */
  483. }
  484. void onButtonD(Gwen::Controls::Base* pControl)
  485. {
  486. /* Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
  487. Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
  488. Gwen::String laa = Gwen::Utility::UnicodeToString(la);
  489. const char* ha = laa.c_str();
  490. */
  491. // printf("onKeyReturn ! \n");
  492. if (!gDisableDemoSelection )
  493. {
  494. selectDemo(sCurrentHightlighted);
  495. saveCurrentSettings(sCurrentDemoIndex, startFileName);
  496. }
  497. }
  498. void onButtonE(Gwen::Controls::Base* pControl)
  499. {
  500. // printf("select %d\n",m_buttonId);
  501. sCurrentHightlighted = m_buttonId;
  502. gui2->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted));
  503. }
  504. void onButtonF(Gwen::Controls::Base* pControl)
  505. {
  506. //printf("selection changed!\n");
  507. }
  508. void onButtonG(Gwen::Controls::Base* pControl)
  509. {
  510. //printf("onButtonG !\n");
  511. }
  512. };
  513. void quitCallback()
  514. {
  515. s_window->setRequestExit();
  516. }
  517. void fileOpenCallback()
  518. {
  519. char filename[1024];
  520. int len = s_window->fileOpenDialog(filename,1024);
  521. if (len)
  522. {
  523. //todo(erwincoumans) check if it is actually URDF
  524. //printf("file open:%s\n", filename);
  525. openFileDemo(filename);
  526. }
  527. }
  528. #define MAX_GRAPH_WINDOWS 5
  529. struct QuickCanvas : public Common2dCanvasInterface
  530. {
  531. GL3TexLoader* m_myTexLoader;
  532. MyGraphWindow* m_gw[MAX_GRAPH_WINDOWS];
  533. GraphingTexture* m_gt[MAX_GRAPH_WINDOWS];
  534. int m_curNumGraphWindows;
  535. int m_curXpos;
  536. QuickCanvas(GL3TexLoader* myTexLoader)
  537. :m_myTexLoader(myTexLoader),
  538. m_curNumGraphWindows(0),
  539. m_curXpos(0)
  540. {
  541. for (int i=0;i<MAX_GRAPH_WINDOWS;i++)
  542. {
  543. m_gw[i] = 0;
  544. m_gt[i] = 0;
  545. }
  546. }
  547. virtual ~QuickCanvas() {}
  548. virtual int createCanvas(const char* canvasName, int width, int height)
  549. {
  550. if (m_curNumGraphWindows<MAX_GRAPH_WINDOWS)
  551. {
  552. //find a slot
  553. int slot = m_curNumGraphWindows;
  554. btAssert(slot<MAX_GRAPH_WINDOWS);
  555. if (slot>=MAX_GRAPH_WINDOWS)
  556. return 0;//don't crash
  557. m_curNumGraphWindows++;
  558. MyGraphInput input(gui2->getInternalData());
  559. input.m_width=width;
  560. input.m_height=height;
  561. input.m_xPos = m_curXpos;//GUI will clamp it to the right//300;
  562. m_curXpos+=width+20;
  563. input.m_yPos = 10000;//GUI will clamp it to bottom
  564. input.m_name=canvasName;
  565. input.m_texName = canvasName;
  566. m_gt[slot] = new GraphingTexture;
  567. m_gt[slot]->create(width,height);
  568. int texId = m_gt[slot]->getTextureId();
  569. m_myTexLoader->m_hashMap.insert(canvasName, texId);
  570. m_gw[slot] = setupTextureWindow(input);
  571. return slot;
  572. }
  573. return -1;
  574. }
  575. virtual void destroyCanvas(int canvasId)
  576. {
  577. m_curXpos = 0;
  578. btAssert(canvasId>=0);
  579. delete m_gt[canvasId];
  580. m_gt[canvasId] = 0;
  581. destroyTextureWindow(m_gw[canvasId]);
  582. m_gw[canvasId] = 0;
  583. m_curNumGraphWindows--;
  584. }
  585. virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)
  586. {
  587. btAssert(canvasId>=0);
  588. btAssert(canvasId<m_curNumGraphWindows);
  589. m_gt[canvasId]->setPixel(x,y,red,green,blue,alpha);
  590. }
  591. virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green,unsigned char& blue, unsigned char& alpha)
  592. {
  593. btAssert(canvasId>=0);
  594. btAssert(canvasId<m_curNumGraphWindows);
  595. m_gt[canvasId]->getPixel(x,y,red,green,blue,alpha);
  596. }
  597. virtual void refreshImageData(int canvasId)
  598. {
  599. m_gt[canvasId]->uploadImageData();
  600. }
  601. };
  602. OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples)
  603. {
  604. m_internalData = new OpenGLExampleBrowserInternalData;
  605. gAllExamples = examples;
  606. }
  607. OpenGLExampleBrowser::~OpenGLExampleBrowser()
  608. {
  609. deleteDemo();
  610. for (int i = 0; i < m_internalData->m_nodes.size(); i++)
  611. {
  612. delete m_internalData->m_nodes[i];
  613. }
  614. delete m_internalData->m_handler2;
  615. for (int i = 0; i < m_internalData->m_handlers.size(); i++)
  616. {
  617. delete m_internalData->m_handlers[i];
  618. }
  619. m_internalData->m_handlers.clear();
  620. m_internalData->m_nodes.clear();
  621. delete s_parameterInterface;
  622. s_parameterInterface = 0;
  623. delete s_app->m_2dCanvasInterface;
  624. s_app->m_2dCanvasInterface = 0;
  625. m_internalData->m_gui->exit();
  626. delete m_internalData->m_gui;
  627. delete m_internalData->m_gwenRenderer;
  628. delete m_internalData->m_myTexLoader;
  629. delete m_internalData->m_app;
  630. s_app = 0;
  631. // delete m_internalData->m_profWindow;
  632. delete m_internalData;
  633. gFileImporterByExtension.clear();
  634. gAllExamples = 0;
  635. }
  636. #include "EmptyExample.h"
  637. bool OpenGLExampleBrowser::init(int argc, char* argv[])
  638. {
  639. b3CommandLineArgs args(argc,argv);
  640. loadCurrentSettings(startFileName, args);
  641. args.GetCmdLineArgument("fixed_timestep",gFixedTimeStep);
  642. args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames);
  643. ///The OpenCL rigid body pipeline is experimental and
  644. ///most OpenCL drivers and OpenCL compilers have issues with our kernels.
  645. ///If you have a high-end desktop GPU such as AMD 7970 or better, or NVIDIA GTX 680 with up-to-date drivers
  646. ///you could give it a try
  647. ///Note that several old OpenCL physics examples still have to be ported over to this new Example Browser
  648. if (args.CheckCmdLineFlag("enable_experimental_opencl"))
  649. {
  650. enable_experimental_opencl = true;
  651. gAllExamples->initOpenCLExampleEntries();
  652. }
  653. if (args.CheckCmdLineFlag("disable_retina"))
  654. {
  655. gAllowRetina = false;
  656. }
  657. int width = 1024;
  658. int height=768;
  659. #ifndef NO_OPENGL3
  660. SimpleOpenGL3App* simpleApp=0;
  661. sUseOpenGL2 =args.CheckCmdLineFlag("opengl2");
  662. #else
  663. sUseOpenGL2 = true;
  664. #endif
  665. const char* appTitle = "Bullet Physics ExampleBrowser";
  666. #if defined (_DEBUG) || defined (DEBUG)
  667. const char* optMode = "Debug build (slow)";
  668. #else
  669. const char* optMode = "Release build";
  670. #endif
  671. if (sUseOpenGL2 )
  672. {
  673. char title[1024];
  674. sprintf(title,"%s using limited OpenGL2 fallback. %s", appTitle,optMode);
  675. s_app = new SimpleOpenGL2App(title,width,height);
  676. s_app->m_renderer = new SimpleOpenGL2Renderer(width,height);
  677. }
  678. #ifndef NO_OPENGL3
  679. else
  680. {
  681. char title[1024];
  682. sprintf(title,"%s using OpenGL3+. %s", appTitle,optMode);
  683. simpleApp = new SimpleOpenGL3App(title,width,height, gAllowRetina);
  684. s_app = simpleApp;
  685. }
  686. #endif
  687. m_internalData->m_app = s_app;
  688. char* gVideoFileName = 0;
  689. args.GetCmdLineArgument("mp4",gVideoFileName);
  690. #ifndef NO_OPENGL3
  691. if (gVideoFileName)
  692. simpleApp->dumpFramesToVideo(gVideoFileName);
  693. #endif
  694. s_instancingRenderer = s_app->m_renderer;
  695. s_window = s_app->m_window;
  696. width = s_window->getWidth();
  697. height = s_window->getHeight();
  698. prevMouseMoveCallback = s_window->getMouseMoveCallback();
  699. s_window->setMouseMoveCallback(MyMouseMoveCallback);
  700. prevMouseButtonCallback = s_window->getMouseButtonCallback();
  701. s_window->setMouseButtonCallback(MyMouseButtonCallback);
  702. prevKeyboardCallback = s_window->getKeyboardCallback();
  703. s_window->setKeyboardCallback(MyKeyboardCallback);
  704. s_app->m_renderer->getActiveCamera()->setCameraDistance(13);
  705. s_app->m_renderer->getActiveCamera()->setCameraPitch(0);
  706. s_app->m_renderer->getActiveCamera()->setCameraTargetPosition(0,0,0);
  707. float mouseMoveMult= s_app->getMouseMoveMultiplier();
  708. if (args.GetCmdLineArgument("mouse_move_multiplier", mouseMoveMult))
  709. {
  710. s_app->setMouseMoveMultiplier(mouseMoveMult);
  711. }
  712. float mouseWheelMult= s_app->getMouseWheelMultiplier();
  713. if (args.GetCmdLineArgument("mouse_wheel_multiplier",mouseWheelMult))
  714. {
  715. s_app->setMouseWheelMultiplier(mouseWheelMult);
  716. }
  717. args.GetCmdLineArgument("shared_memory_key", gSharedMemoryKey);
  718. float red,green,blue;
  719. s_app->getBackgroundColor(&red,&green,&blue);
  720. args.GetCmdLineArgument("background_color_red",red);
  721. args.GetCmdLineArgument("background_color_green",green);
  722. args.GetCmdLineArgument("background_color_blue",blue);
  723. s_app->setBackgroundColor(red,green,blue);
  724. b3SetCustomWarningMessageFunc(MyGuiPrintf);
  725. b3SetCustomPrintfFunc(MyGuiPrintf);
  726. b3SetCustomErrorMessageFunc(MyStatusBarError);
  727. assert(glGetError()==GL_NO_ERROR);
  728. {
  729. GL3TexLoader* myTexLoader = new GL3TexLoader;
  730. m_internalData->m_myTexLoader = myTexLoader;
  731. if (sUseOpenGL2)
  732. {
  733. m_internalData->m_gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont();
  734. }
  735. #ifndef NO_OPENGL3
  736. else
  737. {
  738. sth_stash* fontstash = simpleApp->getFontStash();
  739. m_internalData->m_gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer, fontstash, width, height, s_window->getRetinaScale(), myTexLoader);
  740. }
  741. #endif
  742. gui2 = new GwenUserInterface;
  743. m_internalData->m_gui = gui2;
  744. m_internalData->m_myTexLoader = myTexLoader;
  745. gui2->init(width, height, m_internalData->m_gwenRenderer, s_window->getRetinaScale());
  746. }
  747. //gui = 0;// new GwenUserInterface;
  748. GL3TexLoader* myTexLoader = m_internalData->m_myTexLoader;
  749. // = myTexLoader;
  750. //
  751. if (gui2)
  752. {
  753. // gui->getInternalData()->m_explorerPage
  754. Gwen::Controls::TreeControl* tree = gui2->getInternalData()->m_explorerTreeCtrl;
  755. //gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
  756. // s_profWindow= setupProfileWindow(gui2->getInternalData());
  757. //m_internalData->m_profWindow = s_profWindow;
  758. // profileWindowSetVisible(s_profWindow,false);
  759. gui2->setFocus();
  760. s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData());
  761. s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader);
  762. ///add some demos to the gAllExamples
  763. int numDemos = gAllExamples->getNumRegisteredExamples();
  764. //char nodeText[1024];
  765. //int curDemo = 0;
  766. int selectedDemo = 0;
  767. Gwen::Controls::TreeNode* curNode = tree;
  768. m_internalData->m_handler2 = new MyMenuItemHander(-1);
  769. char* demoNameFromCommandOption = 0;
  770. args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption);
  771. if (demoNameFromCommandOption) {
  772. selectedDemo = -1;
  773. }
  774. tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD);
  775. int firstAvailableDemoIndex=-1;
  776. Gwen::Controls::TreeNode* firstNode=0;
  777. for (int d = 0; d<numDemos; d++)
  778. {
  779. // sprintf(nodeText, "Node %d", i);
  780. Gwen::UnicodeString nodeUText = Gwen::Utility::StringToUnicode(gAllExamples->getExampleName(d));
  781. if (gAllExamples->getExampleCreateFunc(d))//was test for gAllExamples[d].m_menuLevel==1
  782. {
  783. Gwen::Controls::TreeNode* pNode = curNode->AddNode(nodeUText);
  784. if (firstAvailableDemoIndex<0)
  785. {
  786. firstAvailableDemoIndex = d;
  787. firstNode = pNode;
  788. }
  789. if (d == selectedDemo)
  790. {
  791. firstAvailableDemoIndex = d;
  792. firstNode = pNode;
  793. //pNode->SetSelected(true);
  794. //tree->ExpandAll();
  795. // tree->ForceUpdateScrollBars();
  796. //tree->OnKeyLeft(true);
  797. // tree->OnKeyRight(true);
  798. //tree->ExpandAll();
  799. // selectDemo(d);
  800. }
  801. if (demoNameFromCommandOption )
  802. {
  803. const char* demoName = gAllExamples->getExampleName(d);
  804. int res = strcmp(demoName, demoNameFromCommandOption);
  805. if (res==0)
  806. {
  807. firstAvailableDemoIndex = d;
  808. firstNode = pNode;
  809. }
  810. }
  811. #if 1
  812. MyMenuItemHander* handler = new MyMenuItemHander(d);
  813. m_internalData->m_handlers.push_back(handler);
  814. pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA);
  815. pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB);
  816. pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC);
  817. pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE);
  818. pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG);
  819. pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF);
  820. #endif
  821. // pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD);
  822. // pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD);
  823. // pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD);
  824. // pNode->onKeyboardPressed.Add(handler, &MyMenuItemHander::onButtonD);
  825. // pNode->OnKeyPress
  826. }
  827. else
  828. {
  829. curNode = tree->AddNode(nodeUText);
  830. m_internalData->m_nodes.push_back(curNode);
  831. }
  832. }
  833. if (sCurrentDemo==0)
  834. {
  835. if (firstAvailableDemoIndex>=0)
  836. {
  837. firstNode->SetSelected(true);
  838. while (firstNode != tree)
  839. {
  840. firstNode->ExpandAll();
  841. firstNode = (Gwen::Controls::TreeNode*)firstNode->GetParent();
  842. }
  843. selectDemo(firstAvailableDemoIndex);
  844. }
  845. }
  846. free(demoNameFromCommandOption);
  847. demoNameFromCommandOption = 0;
  848. btAssert(sCurrentDemo!=0);
  849. if (sCurrentDemo==0)
  850. {
  851. printf("Error, no demo/example\n");
  852. exit(0);
  853. }
  854. gui2->registerFileOpenCallback(fileOpenCallback);
  855. gui2->registerQuitCallback(quitCallback);
  856. }
  857. return true;
  858. }
  859. CommonExampleInterface* OpenGLExampleBrowser::getCurrentExample()
  860. {
  861. btAssert(sCurrentDemo);
  862. return sCurrentDemo;
  863. }
  864. bool OpenGLExampleBrowser::requestedExit()
  865. {
  866. return s_window->requestedExit();
  867. }
  868. void OpenGLExampleBrowser::update(float deltaTime)
  869. {
  870. B3_PROFILE("OpenGLExampleBrowser::update");
  871. assert(glGetError()==GL_NO_ERROR);
  872. s_instancingRenderer->init();
  873. DrawGridData dg;
  874. dg.upAxis = s_app->getUpAxis();
  875. {
  876. BT_PROFILE("Update Camera and Light");
  877. s_instancingRenderer->updateCamera(dg.upAxis);
  878. }
  879. static int frameCount = 0;
  880. frameCount++;
  881. if (0)
  882. {
  883. BT_PROFILE("Draw frame counter");
  884. char bla[1024];
  885. sprintf(bla,"Frame %d", frameCount);
  886. s_app->drawText(bla,10,10);
  887. }
  888. if (gPngFileName)
  889. {
  890. static int skip = 0;
  891. skip--;
  892. if (skip<0)
  893. {
  894. skip=gPngSkipFrames;
  895. //printf("gPngFileName=%s\n",gPngFileName);
  896. static int s_frameCount = 100;
  897. sprintf(staticPngFileName,"%s%d.png",gPngFileName,s_frameCount++);
  898. //b3Printf("Made screenshot %s",staticPngFileName);
  899. s_app->dumpNextFrameToPng(staticPngFileName);
  900. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  901. }
  902. }
  903. if (sCurrentDemo)
  904. {
  905. if (!pauseSimulation || singleStepSimulation)
  906. {
  907. singleStepSimulation = false;
  908. //printf("---------------------------------------------------\n");
  909. //printf("Framecount = %d\n",frameCount);
  910. B3_PROFILE("sCurrentDemo->stepSimulation");
  911. if (gFixedTimeStep>0)
  912. {
  913. sCurrentDemo->stepSimulation(gFixedTimeStep);
  914. } else
  915. {
  916. sCurrentDemo->stepSimulation(deltaTime);//1./60.f);
  917. }
  918. }
  919. if (renderGrid)
  920. {
  921. BT_PROFILE("Draw Grid");
  922. glPolygonOffset(3.0, 3);
  923. glEnable(GL_POLYGON_OFFSET_FILL);
  924. s_app->drawGrid(dg);
  925. }
  926. if (renderVisualGeometry && ((gDebugDrawFlags&btIDebugDraw::DBG_DrawWireframe)==0))
  927. {
  928. if (visualWireframe)
  929. {
  930. glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  931. }
  932. BT_PROFILE("Render Scene");
  933. sCurrentDemo->renderScene();
  934. }
  935. {
  936. B3_PROFILE("physicsDebugDraw");
  937. glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
  938. sCurrentDemo->physicsDebugDraw(gDebugDrawFlags);
  939. }
  940. }
  941. {
  942. if (gui2 && s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera())
  943. {
  944. B3_PROFILE("setStatusBarMessage");
  945. char msg[1024];
  946. float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance();
  947. float pitch = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPitch();
  948. float yaw = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraYaw();
  949. float camTarget[3];
  950. s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget);
  951. sprintf(msg,"dist=%f, pitch=%f, yaw=%f,target=%f,%f,%f", camDist,pitch,yaw,camTarget[0],camTarget[1],camTarget[2]);
  952. gui2->setStatusBarMessage(msg, true);
  953. }
  954. }
  955. static int toggle = 1;
  956. if (renderGui)
  957. {
  958. B3_PROFILE("renderGui");
  959. // if (!pauseSimulation)
  960. // processProfileData(s_profWindow,false);
  961. if (sUseOpenGL2)
  962. {
  963. saveOpenGLState(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
  964. }
  965. if (m_internalData->m_gui)
  966. {
  967. m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
  968. }
  969. if (gui2)
  970. {
  971. gui2->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
  972. }
  973. if (sUseOpenGL2)
  974. {
  975. restoreOpenGLState();
  976. }
  977. }
  978. toggle=1-toggle;
  979. {
  980. BT_PROFILE("Sync Parameters");
  981. if (s_parameterInterface)
  982. {
  983. s_parameterInterface->syncParameters();
  984. }
  985. }
  986. {
  987. BT_PROFILE("Swap Buffers");
  988. s_app->swapBuffer();
  989. }
  990. if (gui2)
  991. {
  992. B3_PROFILE("forceUpdateScrollBars");
  993. gui2->forceUpdateScrollBars();
  994. }
  995. }
  996. void OpenGLExampleBrowser::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
  997. {
  998. gDisableDemoSelection = true;
  999. sSharedMem = sharedMem;
  1000. }