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 #ifdef BT_USE_EGL
17 #include "../OpenGLWindow/EGLOpenGLWindow.h"
18 #else
19 #include "../OpenGLWindow/X11OpenGLWindow.h"
20 #endif  //BT_USE_EGL
21 #endif  //_WIN32
22 #endif  //__APPLE__
23 #include "../ThirdPartyLibs/Gwen/Renderers/OpenGL_DebugFont.h"
24 #include "LinearMath/btThreads.h"
25 #include "Bullet3Common/b3Vector3.h"
26 #include "assert.h"
27 #include <stdio.h>
28 #include "GwenGUISupport/gwenInternalData.h"
29 #include "GwenGUISupport/gwenUserInterface.h"
30 #include "../Utils/b3Clock.h"
31 #include "../Utils/ChromeTraceUtil.h"
32 #include "GwenGUISupport/GwenParameterInterface.h"
33 #ifndef BT_NO_PROFILE
34 #include "GwenGUISupport/GwenProfileWindow.h"
35 #endif
36 #include "GwenGUISupport/GwenTextureWindow.h"
37 #include "GwenGUISupport/GraphingTexture.h"
38 #include "../CommonInterfaces/Common2dCanvasInterface.h"
39 #include "../CommonInterfaces/CommonExampleInterface.h"
40 #include "Bullet3Common/b3CommandLineArgs.h"
41 #include "../OpenGLWindow/SimpleCamera.h"
42 #include "../OpenGLWindow/SimpleOpenGL2Renderer.h"
43 #include "ExampleEntries.h"
44 #include "OpenGLGuiHelper.h"
45 #include "Bullet3Common/b3FileUtils.h"
46 
47 #include "LinearMath/btIDebugDraw.h"
48 //quick test for file import, @todo(erwincoumans) make it more general and add other file formats
49 #include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
50 #include "../Importers/ImportBullet/SerializeSetup.h"
51 #include "Bullet3Common/b3HashMap.h"
52 
53 struct GL3TexLoader : public MyTextureLoader
54 {
55 	b3HashMap<b3HashString, GLint> m_hashMap;
56 
LoadTextureGL3TexLoader57 	virtual void LoadTexture(Gwen::Texture* pTexture)
58 	{
59 		Gwen::String namestr = pTexture->name.Get();
60 		const char* n = namestr.c_str();
61 		GLint* texIdPtr = m_hashMap[n];
62 		if (texIdPtr)
63 		{
64 			pTexture->m_intData = *texIdPtr;
65 		}
66 	}
FreeTextureGL3TexLoader67 	virtual void FreeTexture(Gwen::Texture* pTexture)
68 	{
69 	}
70 };
71 
72 struct OpenGLExampleBrowserInternalData
73 {
74 	Gwen::Renderer::Base* m_gwenRenderer;
75 	CommonGraphicsApp* m_app;
76 #ifndef BT_NO_PROFILE
77 	MyProfileWindow* m_profWindow;
78 #endif  //BT_NO_PROFILE
79 	btAlignedObjectArray<Gwen::Controls::TreeNode*> m_nodes;
80 	GwenUserInterface* m_gui;
81 	GL3TexLoader* m_myTexLoader;
82 	struct MyMenuItemHander* m_handler2;
83 	btAlignedObjectArray<MyMenuItemHander*> m_handlers;
84 
OpenGLExampleBrowserInternalDataOpenGLExampleBrowserInternalData85 	OpenGLExampleBrowserInternalData()
86 		: m_gwenRenderer(0),
87 		  m_app(0),
88 		  //		m_profWindow(0),
89 		  m_gui(0),
90 		  m_myTexLoader(0),
91 		  m_handler2(0)
92 	{
93 	}
94 };
95 
96 static CommonGraphicsApp* s_app = 0;
97 
98 static CommonWindowInterface* s_window = 0;
99 static CommonParameterInterface* s_parameterInterface = 0;
100 static CommonRenderInterface* s_instancingRenderer = 0;
101 static OpenGLGuiHelper* s_guiHelper = 0;
102 #ifndef BT_NO_PROFILE
103 static MyProfileWindow* s_profWindow = 0;
104 #endif  //BT_NO_PROFILE
105 static SharedMemoryInterface* sSharedMem = 0;
106 
107 #define DEMO_SELECTION_COMBOBOX 13
108 const char* startFileName = "0_Bullet3Demo.txt";
109 char staticPngFileName[1024];
110 //static GwenUserInterface* gui  = 0;
111 static GwenUserInterface* gui2 = 0;
112 static int sCurrentDemoIndex = -1;
113 static int sCurrentHightlighted = 0;
114 static CommonExampleInterface* sCurrentDemo = 0;
115 static b3AlignedObjectArray<const char*> allNames;
116 static float gFixedTimeStep = 0;
117 bool gAllowRetina = true;
118 bool gDisableDemoSelection = false;
119 int gRenderDevice = -1;
120 int gWindowBackend = 0;
121 static class ExampleEntries* gAllExamples = 0;
122 bool sUseOpenGL2 = false;
123 #ifndef USE_OPENGL3
124 extern bool useShadowMap;
125 #endif
126 
127 bool visualWireframe = false;
128 static bool renderVisualGeometry = true;
129 static bool renderGrid = true;
130 static bool gEnableRenderLoop = true;
131 
132 bool renderGui = true;
133 static bool enable_experimental_opencl = false;
134 
135 static bool gEnableDefaultKeyboardShortcuts = true;
136 static bool gEnableDefaultMousePicking = true;
137 
138 int gDebugDrawFlags = 0;
139 static bool pauseSimulation = false;
140 static bool singleStepSimulation = false;
141 int midiBaseIndex = 176;
142 extern bool gDisableDeactivation;
143 
144 int gSharedMemoryKey = -1;
145 
146 ///some quick test variable for the OpenCL examples
147 
148 int gPreferredOpenCLDeviceIndex = -1;
149 int gPreferredOpenCLPlatformIndex = -1;
150 int gGpuArraySizeX = 45;
151 int gGpuArraySizeY = 55;
152 int gGpuArraySizeZ = 45;
153 
154 //#include <float.h>
155 //unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);
156 
deleteDemo()157 void deleteDemo()
158 {
159 	if (sCurrentDemo)
160 	{
161 		sCurrentDemo->exitPhysics();
162 		s_instancingRenderer->removeAllInstances();
163 		delete sCurrentDemo;
164 		sCurrentDemo = 0;
165 		delete s_guiHelper;
166 		s_guiHelper = 0;
167 
168 		//		CProfileManager::CleanupMemory();
169 	}
170 }
171 
172 const char* gPngFileName = 0;
173 int gPngSkipFrames = 0;
174 
175 b3KeyboardCallback prevKeyboardCallback = 0;
176 
MyKeyboardCallback(int key,int state)177 void MyKeyboardCallback(int key, int state)
178 {
179 	//b3Printf("key=%d, state=%d", key, state);
180 	bool handled = false;
181 	if (renderGui)
182 	{
183 		if (gui2 && !handled)
184 		{
185 			handled = gui2->keyboardCallback(key, state);
186 		}
187 	}
188 
189 	if (!handled && sCurrentDemo)
190 	{
191 		handled = sCurrentDemo->keyboardCallback(key, state);
192 	}
193 
194 	//checkout: is it desired to ignore keys, if the demo already handles them?
195 	//if (handled)
196 	//	return;
197 
198 	if (gEnableDefaultKeyboardShortcuts)
199 	{
200 		if (key == 'a' && state)
201 		{
202 			gDebugDrawFlags ^= btIDebugDraw::DBG_DrawAabb;
203 		}
204 		if (key == 'c' && state)
205 		{
206 			gDebugDrawFlags ^= btIDebugDraw::DBG_DrawContactPoints;
207 		}
208 		if (key == 'd' && state)
209 		{
210 			gDebugDrawFlags ^= btIDebugDraw::DBG_NoDeactivation;
211 			gDisableDeactivation = ((gDebugDrawFlags & btIDebugDraw::DBG_NoDeactivation) != 0);
212 		}
213 		if (key == 'j' && state)
214 		{
215 			gDebugDrawFlags ^= btIDebugDraw::DBG_DrawFrames;
216 		}
217 
218 		if (key == 'k' && state)
219 		{
220 			gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraints;
221 		}
222 
223 		if (key == 'l' && state)
224 		{
225 			gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraintLimits;
226 		}
227 		if (key == 'w' && state)
228 		{
229 			visualWireframe = !visualWireframe;
230 			gDebugDrawFlags ^= btIDebugDraw::DBG_DrawWireframe;
231 		}
232 
233 		if (key == 'v' && state)
234 		{
235 			renderVisualGeometry = !renderVisualGeometry;
236 		}
237 		if (key == 'g' && state)
238 		{
239 			renderGrid = !renderGrid;
240 			renderGui = !renderGui;
241 		}
242 
243 		if (key == 'i' && state)
244 		{
245 			pauseSimulation = !pauseSimulation;
246 		}
247 		if (key == 'o' && state)
248 		{
249 			singleStepSimulation = true;
250 		}
251 
252 		if (key == 'p')
253 		{
254 			if (state)
255 			{
256 				b3ChromeUtilsStartTimings();
257 			}
258 			else
259 			{
260 #ifdef _WIN32
261 				b3ChromeUtilsStopTimingsAndWriteJsonFile("timings");
262 #else
263 				b3ChromeUtilsStopTimingsAndWriteJsonFile("/tmp/timings");
264 #endif
265 			}
266 		}
267 
268 #ifndef NO_OPENGL3
269 		if (key == 's' && state)
270 		{
271 			useShadowMap = !useShadowMap;
272 		}
273 #endif
274 		if (key == B3G_F1)
275 		{
276 			static int count = 0;
277 			if (state)
278 			{
279 				b3Printf("F1 pressed %d", count++);
280 
281 				if (gPngFileName)
282 				{
283 					b3Printf("disable image dump");
284 
285 					gPngFileName = 0;
286 				}
287 				else
288 				{
289 					gPngFileName = gAllExamples->getExampleName(sCurrentDemoIndex);
290 					b3Printf("enable image dump %s", gPngFileName);
291 				}
292 			}
293 			else
294 			{
295 				b3Printf("F1 released %d", count++);
296 			}
297 		}
298 	}
299 	if (key == B3G_ESCAPE && s_window)
300 	{
301 		s_window->setRequestExit();
302 	}
303 
304 	if (prevKeyboardCallback)
305 		prevKeyboardCallback(key, state);
306 }
307 
308 b3MouseMoveCallback prevMouseMoveCallback = 0;
MyMouseMoveCallback(float x,float y)309 static void MyMouseMoveCallback(float x, float y)
310 {
311 	bool handled = false;
312 	if (sCurrentDemo)
313 		handled = sCurrentDemo->mouseMoveCallback(x, y);
314 	if (renderGui)
315 	{
316 		if (!handled && gui2)
317 			handled = gui2->mouseMoveCallback(x, y);
318 	}
319 	if (!handled)
320 	{
321 		if (prevMouseMoveCallback)
322 			prevMouseMoveCallback(x, y);
323 	}
324 }
325 
326 b3MouseButtonCallback prevMouseButtonCallback = 0;
327 
MyMouseButtonCallback(int button,int state,float x,float y)328 static void MyMouseButtonCallback(int button, int state, float x, float y)
329 {
330 	bool handled = false;
331 	//try picking first
332 	if (sCurrentDemo)
333 		handled = sCurrentDemo->mouseButtonCallback(button, state, x, y);
334 
335 	if (renderGui)
336 	{
337 		if (!handled && gui2)
338 			handled = gui2->mouseButtonCallback(button, state, x, y);
339 	}
340 	if (!handled)
341 	{
342 		if (prevMouseButtonCallback)
343 			prevMouseButtonCallback(button, state, x, y);
344 	}
345 	//	b3DefaultMouseButtonCallback(button,state,x,y);
346 }
347 
348 #include <string.h>
349 struct FileImporterByExtension
350 {
351 	std::string m_extension;
352 	CommonExampleInterface::CreateFunc* m_createFunc;
353 };
354 
355 static btAlignedObjectArray<FileImporterByExtension> gFileImporterByExtension;
356 
registerFileImporter(const char * extension,CommonExampleInterface::CreateFunc * createFunc)357 void OpenGLExampleBrowser::registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc)
358 {
359 	FileImporterByExtension fi;
360 	fi.m_extension = extension;
361 	fi.m_createFunc = createFunc;
362 	gFileImporterByExtension.push_back(fi);
363 }
364 #include "../SharedMemory/SharedMemoryPublic.h"
365 
OpenGLExampleBrowserVisualizerFlagCallback(int flag,bool enable)366 void OpenGLExampleBrowserVisualizerFlagCallback(int flag, bool enable)
367 {
368 	if (flag == COV_ENABLE_Y_AXIS_UP)
369 	{
370 		//either Y = up or Z
371 		int upAxis = enable ? 1 : 2;
372 		s_app->setUpAxis(upAxis);
373 	}
374 
375 	if (flag == COV_ENABLE_RENDERING)
376 	{
377 		gEnableRenderLoop = (enable != 0);
378 	}
379 
380 	if (flag == COV_ENABLE_SINGLE_STEP_RENDERING)
381 	{
382 		if (enable)
383 		{
384 			gEnableRenderLoop = false;
385 			singleStepSimulation = true;
386 		}
387 		else
388 		{
389 			gEnableRenderLoop = true;
390 			singleStepSimulation = false;
391 		}
392 	}
393 
394 	if (flag == COV_ENABLE_SHADOWS)
395 	{
396 		useShadowMap = enable;
397 	}
398 	if (flag == COV_ENABLE_GUI)
399 	{
400 		renderGui = enable;
401 		renderGrid = enable;
402 	}
403 
404 	if (flag == COV_ENABLE_KEYBOARD_SHORTCUTS)
405 	{
406 		gEnableDefaultKeyboardShortcuts = enable;
407 	}
408 	if (flag == COV_ENABLE_MOUSE_PICKING)
409 	{
410 		gEnableDefaultMousePicking = enable;
411 	}
412 
413 	if (flag == COV_ENABLE_WIREFRAME)
414 	{
415 		visualWireframe = enable;
416 		if (visualWireframe)
417 		{
418 			gDebugDrawFlags |= btIDebugDraw::DBG_DrawWireframe;
419 		}
420 		else
421 		{
422 			gDebugDrawFlags &= ~btIDebugDraw::DBG_DrawWireframe;
423 		}
424 	}
425 }
426 
openFileDemo(const char * filename)427 void openFileDemo(const char* filename)
428 {
429 	deleteDemo();
430 
431 	s_guiHelper = new OpenGLGuiHelper(s_app, sUseOpenGL2);
432 	s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback);
433 
434 	s_parameterInterface->removeAllParameters();
435 
436 	CommonExampleOptions options(s_guiHelper, 1);
437 	options.m_fileName = filename;
438 	char fullPath[1024];
439 	sprintf(fullPath, "%s", filename);
440 	b3FileUtils::toLower(fullPath);
441 
442 	for (int i = 0; i < gFileImporterByExtension.size(); i++)
443 	{
444 		if (strstr(fullPath, gFileImporterByExtension[i].m_extension.c_str()))
445 		{
446 			sCurrentDemo = gFileImporterByExtension[i].m_createFunc(options);
447 		}
448 	}
449 
450 	if (sCurrentDemo)
451 	{
452 		sCurrentDemo->initPhysics();
453 		sCurrentDemo->resetCamera();
454 	}
455 }
456 
selectDemo(int demoIndex)457 void selectDemo(int demoIndex)
458 {
459 	bool resetCamera = (sCurrentDemoIndex != demoIndex);
460 	sCurrentDemoIndex = demoIndex;
461 	sCurrentHightlighted = demoIndex;
462 	int numDemos = gAllExamples->getNumRegisteredExamples();
463 
464 	if (demoIndex > numDemos)
465 	{
466 		demoIndex = 0;
467 	}
468 	deleteDemo();
469 
470 	CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex);
471 	if (func)
472 	{
473 		if (s_parameterInterface)
474 		{
475 			s_parameterInterface->removeAllParameters();
476 		}
477 		int option = gAllExamples->getExampleOption(demoIndex);
478 		s_guiHelper = new OpenGLGuiHelper(s_app, sUseOpenGL2);
479 		s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback);
480 
481 		CommonExampleOptions options(s_guiHelper, option);
482 		options.m_sharedMem = sSharedMem;
483 		sCurrentDemo = (*func)(options);
484 		if (sCurrentDemo)
485 		{
486 			if (gui2)
487 			{
488 				gui2->setStatusBarMessage("Status: OK", false);
489 			}
490 			b3Printf("Selected demo: %s", gAllExamples->getExampleName(demoIndex));
491 			if (gui2)
492 			{
493 				gui2->setExampleDescription(gAllExamples->getExampleDescription(demoIndex));
494 			}
495 
496 			sCurrentDemo->initPhysics();
497 			if (resetCamera)
498 			{
499 				sCurrentDemo->resetCamera();
500 			}
501 		}
502 	}
503 }
504 
505 #include <stdio.h>
506 
saveCurrentSettings(int currentEntry,const char * startFileName)507 static void saveCurrentSettings(int currentEntry, const char* startFileName)
508 {
509 	FILE* f = fopen(startFileName, "w");
510 	if (f)
511 	{
512 		fprintf(f, "--start_demo_name=%s\n", gAllExamples->getExampleName(sCurrentDemoIndex));
513 		fprintf(f, "--mouse_move_multiplier=%f\n", s_app->getMouseMoveMultiplier());
514 		fprintf(f, "--mouse_wheel_multiplier=%f\n", s_app->getMouseWheelMultiplier());
515 		float red, green, blue;
516 		s_app->getBackgroundColor(&red, &green, &blue);
517 		fprintf(f, "--background_color_red= %f\n", red);
518 		fprintf(f, "--background_color_green= %f\n", green);
519 		fprintf(f, "--background_color_blue= %f\n", blue);
520 		fprintf(f, "--fixed_timestep= %f\n", gFixedTimeStep);
521 		if (!gAllowRetina)
522 		{
523 			fprintf(f, "--disable_retina");
524 		}
525 
526 		if (enable_experimental_opencl)
527 		{
528 			fprintf(f, "--enable_experimental_opencl\n");
529 		}
530 		//		if (sUseOpenGL2 )
531 		//		{
532 		//			fprintf(f,"--opengl2\n");
533 		//		}
534 
535 		fclose(f);
536 	}
537 };
538 
loadCurrentSettings(const char * startFileName,b3CommandLineArgs & args)539 static void loadCurrentSettings(const char* startFileName, b3CommandLineArgs& args)
540 {
541 	//int currentEntry= 0;
542 	FILE* f = fopen(startFileName, "r");
543 	if (f)
544 	{
545 		char oneline[1024];
546 		char* argv[] = {0, &oneline[0]};
547 
548 		while (fgets(oneline, 1024, f) != NULL)
549 		{
550 			char* pos;
551 			if ((pos = strchr(oneline, '\n')) != NULL)
552 				*pos = '\0';
553 			args.addArgs(2, argv);
554 		}
555 		fclose(f);
556 	}
557 };
558 
MyComboBoxCallback(int comboId,const char * item)559 void MyComboBoxCallback(int comboId, const char* item)
560 {
561 	//printf("comboId = %d, item = %s\n",comboId, item);
562 	if (comboId == DEMO_SELECTION_COMBOBOX)
563 	{
564 		//find selected item
565 		for (int i = 0; i < allNames.size(); i++)
566 		{
567 			if (strcmp(item, allNames[i]) == 0)
568 			{
569 				selectDemo(i);
570 				saveCurrentSettings(sCurrentDemoIndex, startFileName);
571 				break;
572 			}
573 		}
574 	}
575 }
576 
577 //in case of multi-threading, don't submit messages while the GUI is rendering (causing crashes)
578 static bool gBlockGuiMessages = false;
579 
MyGuiPrintf(const char * msg)580 void MyGuiPrintf(const char* msg)
581 {
582 	printf("b3Printf: %s\n", msg);
583 	if (!gDisableDemoSelection && !gBlockGuiMessages)
584 	{
585 		gui2->textOutput(msg);
586 		gui2->forceUpdateScrollBars();
587 	}
588 }
589 
MyStatusBarPrintf(const char * msg)590 void MyStatusBarPrintf(const char* msg)
591 {
592 	printf("b3Printf: %s\n", msg);
593 	if (!gDisableDemoSelection && !gBlockGuiMessages)
594 	{
595 		bool isLeft = true;
596 		gui2->setStatusBarMessage(msg, isLeft);
597 	}
598 }
599 
MyStatusBarError(const char * msg)600 void MyStatusBarError(const char* msg)
601 {
602 	printf("Warning: %s\n", msg);
603 	if (!gDisableDemoSelection && !gBlockGuiMessages)
604 	{
605 		bool isLeft = false;
606 		gui2->setStatusBarMessage(msg, isLeft);
607 		gui2->textOutput(msg);
608 		gui2->forceUpdateScrollBars();
609 	}
610 	btAssert(0);
611 }
612 
613 struct MyMenuItemHander : public Gwen::Event::Handler
614 {
615 	int m_buttonId;
616 
MyMenuItemHanderMyMenuItemHander617 	MyMenuItemHander(int buttonId)
618 		: m_buttonId(buttonId)
619 	{
620 	}
621 
onButtonAMyMenuItemHander622 	void onButtonA(Gwen::Controls::Base* pControl)
623 	{
624 		//const Gwen::String& name = pControl->GetName();
625 		Gwen::Controls::TreeNode* node = (Gwen::Controls::TreeNode*)pControl;
626 		//	Gwen::Controls::Label* l = node->GetButton();
627 
628 		Gwen::UnicodeString la = node->GetButton()->GetText();  // node->GetButton()->GetName();// GetText();
629 		Gwen::String laa = Gwen::Utility::UnicodeToString(la);
630 		//	const char* ha = laa.c_str();
631 
632 		//printf("selected %s\n", ha);
633 		//int dep = but->IsDepressed();
634 		//int tog = but->GetToggleState();
635 		//		if (m_data->m_toggleButtonCallback)
636 		//		(*m_data->m_toggleButtonCallback)(m_buttonId, tog);
637 	}
onButtonBMyMenuItemHander638 	void onButtonB(Gwen::Controls::Base* pControl)
639 	{
640 		Gwen::Controls::Label* label = (Gwen::Controls::Label*)pControl;
641 		Gwen::UnicodeString la = label->GetText();  // node->GetButton()->GetName();// GetText();
642 		Gwen::String laa = Gwen::Utility::UnicodeToString(la);
643 		//const char* ha = laa.c_str();
644 
645 		if (!gDisableDemoSelection)
646 		{
647 			selectDemo(sCurrentHightlighted);
648 			saveCurrentSettings(sCurrentDemoIndex, startFileName);
649 		}
650 	}
onButtonCMyMenuItemHander651 	void onButtonC(Gwen::Controls::Base* pControl)
652 	{
653 		/*Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
654 		Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
655 		Gwen::String laa = Gwen::Utility::UnicodeToString(la);
656 		const char* ha = laa.c_str();
657 
658 
659 		printf("onButtonC ! %s\n", ha);
660 		*/
661 	}
onButtonDMyMenuItemHander662 	void onButtonD(Gwen::Controls::Base* pControl)
663 	{
664 		/*		Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
665 		Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
666 		Gwen::String laa = Gwen::Utility::UnicodeToString(la);
667 		const char* ha = laa.c_str();
668 		*/
669 
670 		//	printf("onKeyReturn ! \n");
671 		if (!gDisableDemoSelection)
672 		{
673 			selectDemo(sCurrentHightlighted);
674 			saveCurrentSettings(sCurrentDemoIndex, startFileName);
675 		}
676 	}
677 
onButtonEMyMenuItemHander678 	void onButtonE(Gwen::Controls::Base* pControl)
679 	{
680 		//	printf("select %d\n",m_buttonId);
681 		sCurrentHightlighted = m_buttonId;
682 		gui2->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted));
683 	}
684 
onButtonFMyMenuItemHander685 	void onButtonF(Gwen::Controls::Base* pControl)
686 	{
687 		//printf("selection changed!\n");
688 	}
689 
onButtonGMyMenuItemHander690 	void onButtonG(Gwen::Controls::Base* pControl)
691 	{
692 		//printf("onButtonG !\n");
693 	}
694 };
695 
quitCallback()696 void quitCallback()
697 {
698 	s_window->setRequestExit();
699 }
700 
fileOpenCallback()701 void fileOpenCallback()
702 {
703 	char filename[1024];
704 	int len = s_window->fileOpenDialog(filename, 1024);
705 	if (len)
706 	{
707 		//todo(erwincoumans) check if it is actually URDF
708 		//printf("file open:%s\n", filename);
709 		openFileDemo(filename);
710 	}
711 }
712 
713 #define MAX_GRAPH_WINDOWS 5
714 
715 struct QuickCanvas : public Common2dCanvasInterface
716 {
717 	GL3TexLoader* m_myTexLoader;
718 
719 	MyGraphWindow* m_gw[MAX_GRAPH_WINDOWS];
720 	GraphingTexture* m_gt[MAX_GRAPH_WINDOWS];
721 	int m_curNumGraphWindows;
722 
QuickCanvasQuickCanvas723 	QuickCanvas(GL3TexLoader* myTexLoader)
724 		: m_myTexLoader(myTexLoader),
725 		  m_curNumGraphWindows(0)
726 	{
727 		for (int i = 0; i < MAX_GRAPH_WINDOWS; i++)
728 		{
729 			m_gw[i] = 0;
730 			m_gt[i] = 0;
731 		}
732 	}
~QuickCanvasQuickCanvas733 	virtual ~QuickCanvas() {}
createCanvasQuickCanvas734 	virtual int createCanvas(const char* canvasName, int width, int height, int xPos, int yPos)
735 	{
736 		if (m_curNumGraphWindows < MAX_GRAPH_WINDOWS)
737 		{
738 			//find a slot
739 			int slot = m_curNumGraphWindows;
740 			btAssert(slot < MAX_GRAPH_WINDOWS);
741 			if (slot >= MAX_GRAPH_WINDOWS)
742 				return 0;  //don't crash
743 
744 			m_curNumGraphWindows++;
745 
746 			MyGraphInput input(gui2->getInternalData());
747 			input.m_width = width;
748 			input.m_height = height;
749 			input.m_xPos = xPos;
750 			input.m_yPos = yPos;
751 			input.m_name = canvasName;
752 			input.m_texName = canvasName;
753 			m_gt[slot] = new GraphingTexture;
754 			m_gt[slot]->create(width, height);
755 			int texId = m_gt[slot]->getTextureId();
756 			m_myTexLoader->m_hashMap.insert(canvasName, texId);
757 			m_gw[slot] = setupTextureWindow(input);
758 
759 			return slot;
760 		}
761 		return -1;
762 	}
destroyCanvasQuickCanvas763 	virtual void destroyCanvas(int canvasId)
764 	{
765 		btAssert(canvasId >= 0);
766 		delete m_gt[canvasId];
767 		m_gt[canvasId] = 0;
768 		destroyTextureWindow(m_gw[canvasId]);
769 		m_gw[canvasId] = 0;
770 		m_curNumGraphWindows--;
771 	}
setPixelQuickCanvas772 	virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
773 	{
774 		btAssert(canvasId >= 0);
775 		btAssert(canvasId < m_curNumGraphWindows);
776 		m_gt[canvasId]->setPixel(x, y, red, green, blue, alpha);
777 	}
778 
getPixelQuickCanvas779 	virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha)
780 	{
781 		btAssert(canvasId >= 0);
782 		btAssert(canvasId < m_curNumGraphWindows);
783 		m_gt[canvasId]->getPixel(x, y, red, green, blue, alpha);
784 	}
785 
refreshImageDataQuickCanvas786 	virtual void refreshImageData(int canvasId)
787 	{
788 		m_gt[canvasId]->uploadImageData();
789 	}
790 };
791 
OpenGLExampleBrowser(class ExampleEntries * examples)792 OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples)
793 {
794 	m_internalData = new OpenGLExampleBrowserInternalData;
795 
796 	gAllExamples = examples;
797 }
798 
~OpenGLExampleBrowser()799 OpenGLExampleBrowser::~OpenGLExampleBrowser()
800 {
801 	deleteDemo();
802 	for (int i = 0; i < m_internalData->m_nodes.size(); i++)
803 	{
804 		delete m_internalData->m_nodes[i];
805 	}
806 	delete m_internalData->m_handler2;
807 	for (int i = 0; i < m_internalData->m_handlers.size(); i++)
808 	{
809 		delete m_internalData->m_handlers[i];
810 	}
811 	m_internalData->m_handlers.clear();
812 	m_internalData->m_nodes.clear();
813 	delete s_parameterInterface;
814 	s_parameterInterface = 0;
815 	delete s_app->m_2dCanvasInterface;
816 	s_app->m_2dCanvasInterface = 0;
817 
818 #ifndef BT_NO_PROFILE
819 	destroyProfileWindow(m_internalData->m_profWindow);
820 #endif
821 
822 	m_internalData->m_gui->exit();
823 
824 	delete m_internalData->m_gui;
825 	delete m_internalData->m_gwenRenderer;
826 	delete m_internalData->m_myTexLoader;
827 
828 	delete m_internalData->m_app;
829 	s_app = 0;
830 
831 	delete m_internalData;
832 
833 	gFileImporterByExtension.clear();
834 	gAllExamples = 0;
835 }
836 
837 #include "EmptyExample.h"
838 
init(int argc,char * argv[])839 bool OpenGLExampleBrowser::init(int argc, char* argv[])
840 {
841 	b3CommandLineArgs args(argc, argv);
842 
843 	loadCurrentSettings(startFileName, args);
844 	if (args.CheckCmdLineFlag("nogui"))
845 	{
846 		renderGrid = false;
847 		renderGui = false;
848 	}
849 	if (args.CheckCmdLineFlag("tracing"))
850 	{
851 		b3ChromeUtilsStartTimings();
852 	}
853 	args.GetCmdLineArgument("fixed_timestep", gFixedTimeStep);
854 	args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames);
855 	///The OpenCL rigid body pipeline is experimental and
856 	///most OpenCL drivers and OpenCL compilers have issues with our kernels.
857 	///If you have a high-end desktop GPU such as AMD 7970 or better, or NVIDIA GTX 680 with up-to-date drivers
858 	///you could give it a try
859 	///Note that several old OpenCL physics examples still have to be ported over to this new Example Browser
860 	if (args.CheckCmdLineFlag("enable_experimental_opencl"))
861 	{
862 		enable_experimental_opencl = true;
863 		gAllExamples->initOpenCLExampleEntries();
864 	}
865 
866 	if (args.CheckCmdLineFlag("disable_retina"))
867 	{
868 		gAllowRetina = false;
869 	}
870 
871 	int width = 1024;
872 	int height = 768;
873 
874 	if (args.CheckCmdLineFlag("width"))
875 	{
876 		args.GetCmdLineArgument("width", width);
877 	}
878 	if (args.CheckCmdLineFlag("height"))
879 	{
880 		args.GetCmdLineArgument("height", height);
881 	}
882 
883 #ifndef NO_OPENGL3
884 	SimpleOpenGL3App* simpleApp = 0;
885 	sUseOpenGL2 = args.CheckCmdLineFlag("opengl2");
886 	args.GetCmdLineArgument("render_device", gRenderDevice);
887 	args.GetCmdLineArgument("window_backend", gWindowBackend);
888 #else
889 	sUseOpenGL2 = true;
890 #endif
891 	const char* appTitle = "Bullet Physics ExampleBrowser";
892 #if defined(_DEBUG) || defined(DEBUG)
893 	const char* optMode = "Debug build (slow)";
894 #else
895 	const char* optMode = "Release build";
896 #endif
897 
898 #ifdef B3_USE_GLFW
899 	const char* glContext = "[glfw]";
900 #else
901 	const char* glContext = "[btgl]";
902 #endif
903 
904 	if (sUseOpenGL2)
905 	{
906 		char title[1024];
907 		sprintf(title, "%s using limited OpenGL2 fallback %s %s", appTitle, glContext, optMode);
908 		s_app = new SimpleOpenGL2App(title, width, height);
909 		s_app->m_renderer = new SimpleOpenGL2Renderer(width, height);
910 	}
911 
912 #ifndef NO_OPENGL3
913 	else
914 	{
915 		char title[1024];
916 		sprintf(title, "%s using OpenGL3+ %s %s", appTitle, glContext, optMode);
917 		simpleApp = new SimpleOpenGL3App(title, width, height, gAllowRetina, gWindowBackend, gRenderDevice);
918 		s_app = simpleApp;
919 	}
920 #endif
921 	m_internalData->m_app = s_app;
922 	char* gVideoFileName = 0;
923 	args.GetCmdLineArgument("mp4", gVideoFileName);
924 	int gVideoFps = 0;
925 	args.GetCmdLineArgument("mp4fps", gVideoFps);
926 	if (gVideoFps)
927 	{
928 		simpleApp->setMp4Fps(gVideoFps);
929 	}
930 
931 #ifndef NO_OPENGL3
932 	if (gVideoFileName)
933 		simpleApp->dumpFramesToVideo(gVideoFileName);
934 #endif
935 
936 	s_instancingRenderer = s_app->m_renderer;
937 	s_window = s_app->m_window;
938 
939 	width = s_window->getWidth();
940 	height = s_window->getHeight();
941 
942 	prevMouseMoveCallback = s_window->getMouseMoveCallback();
943 	s_window->setMouseMoveCallback(MyMouseMoveCallback);
944 
945 	prevMouseButtonCallback = s_window->getMouseButtonCallback();
946 	s_window->setMouseButtonCallback(MyMouseButtonCallback);
947 	prevKeyboardCallback = s_window->getKeyboardCallback();
948 	s_window->setKeyboardCallback(MyKeyboardCallback);
949 
950 	s_app->m_renderer->getActiveCamera()->setCameraDistance(13);
951 	s_app->m_renderer->getActiveCamera()->setCameraPitch(0);
952 	s_app->m_renderer->getActiveCamera()->setCameraTargetPosition(0, 0, 0);
953 
954 	float mouseMoveMult = s_app->getMouseMoveMultiplier();
955 	if (args.GetCmdLineArgument("mouse_move_multiplier", mouseMoveMult))
956 	{
957 		s_app->setMouseMoveMultiplier(mouseMoveMult);
958 	}
959 
960 	float mouseWheelMult = s_app->getMouseWheelMultiplier();
961 	if (args.GetCmdLineArgument("mouse_wheel_multiplier", mouseWheelMult))
962 	{
963 		s_app->setMouseWheelMultiplier(mouseWheelMult);
964 	}
965 
966 	args.GetCmdLineArgument("shared_memory_key", gSharedMemoryKey);
967 
968 	float red, green, blue;
969 	s_app->getBackgroundColor(&red, &green, &blue);
970 	args.GetCmdLineArgument("background_color_red", red);
971 	args.GetCmdLineArgument("background_color_green", green);
972 	args.GetCmdLineArgument("background_color_blue", blue);
973 	s_app->setBackgroundColor(red, green, blue);
974 
975 	b3SetCustomWarningMessageFunc(MyGuiPrintf);
976 	b3SetCustomPrintfFunc(MyGuiPrintf);
977 	b3SetCustomErrorMessageFunc(MyStatusBarError);
978 
979 	assert(glGetError() == GL_NO_ERROR);
980 
981 	{
982 		GL3TexLoader* myTexLoader = new GL3TexLoader;
983 		m_internalData->m_myTexLoader = myTexLoader;
984 
985 		if (sUseOpenGL2)
986 		{
987 			m_internalData->m_gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(s_window->getRetinaScale());
988 		}
989 #ifndef NO_OPENGL3
990 		else
991 		{
992 			sth_stash* fontstash = simpleApp->getFontStash();
993 			m_internalData->m_gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer, fontstash, width, height, s_window->getRetinaScale(), myTexLoader);
994 		}
995 #endif
996 
997 		gui2 = new GwenUserInterface;
998 
999 		m_internalData->m_gui = gui2;
1000 
1001 		m_internalData->m_myTexLoader = myTexLoader;
1002 
1003 		gui2->init(width, height, m_internalData->m_gwenRenderer, s_window->getRetinaScale());
1004 	}
1005 	//gui = 0;// new GwenUserInterface;
1006 
1007 	GL3TexLoader* myTexLoader = m_internalData->m_myTexLoader;
1008 	// = myTexLoader;
1009 
1010 	//
1011 
1012 	if (gui2)
1013 	{
1014 		//	gui->getInternalData()->m_explorerPage
1015 		Gwen::Controls::TreeControl* tree = gui2->getInternalData()->m_explorerTreeCtrl;
1016 
1017 		//gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
1018 
1019 #ifndef BT_NO_PROFILE
1020 		s_profWindow = setupProfileWindow(gui2->getInternalData());
1021 		m_internalData->m_profWindow = s_profWindow;
1022 		profileWindowSetVisible(s_profWindow, false);
1023 #endif  //BT_NO_PROFILE
1024 		gui2->setFocus();
1025 
1026 		s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData());
1027 		s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader);
1028 
1029 		///add some demos to the gAllExamples
1030 
1031 		int numDemos = gAllExamples->getNumRegisteredExamples();
1032 
1033 		//char nodeText[1024];
1034 		//int curDemo = 0;
1035 		int selectedDemo = 0;
1036 		Gwen::Controls::TreeNode* curNode = tree;
1037 		m_internalData->m_handler2 = new MyMenuItemHander(-1);
1038 
1039 		char* demoNameFromCommandOption = 0;
1040 		args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption);
1041 		if (demoNameFromCommandOption)
1042 		{
1043 			selectedDemo = -1;
1044 		}
1045 
1046 		tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD);
1047 		int firstAvailableDemoIndex = -1;
1048 		Gwen::Controls::TreeNode* firstNode = 0;
1049 
1050 		for (int d = 0; d < numDemos; d++)
1051 		{
1052 			//		sprintf(nodeText, "Node %d", i);
1053 			Gwen::UnicodeString nodeUText = Gwen::Utility::StringToUnicode(gAllExamples->getExampleName(d));
1054 			if (gAllExamples->getExampleCreateFunc(d))  //was test for gAllExamples[d].m_menuLevel==1
1055 			{
1056 				Gwen::Controls::TreeNode* pNode = curNode->AddNode(nodeUText);
1057 
1058 				if (firstAvailableDemoIndex < 0)
1059 				{
1060 					firstAvailableDemoIndex = d;
1061 					firstNode = pNode;
1062 				}
1063 
1064 				if (d == selectedDemo)
1065 				{
1066 					firstAvailableDemoIndex = d;
1067 					firstNode = pNode;
1068 					//pNode->SetSelected(true);
1069 					//tree->ExpandAll();
1070 					//	tree->ForceUpdateScrollBars();
1071 					//tree->OnKeyLeft(true);
1072 					//	tree->OnKeyRight(true);
1073 
1074 					//tree->ExpandAll();
1075 
1076 					//	selectDemo(d);
1077 				}
1078 
1079 				if (demoNameFromCommandOption)
1080 				{
1081 					const char* demoName = gAllExamples->getExampleName(d);
1082 					int res = strcmp(demoName, demoNameFromCommandOption);
1083 					if (res == 0)
1084 					{
1085 						firstAvailableDemoIndex = d;
1086 						firstNode = pNode;
1087 					}
1088 				}
1089 
1090 #if 1
1091 				MyMenuItemHander* handler = new MyMenuItemHander(d);
1092 				m_internalData->m_handlers.push_back(handler);
1093 
1094 				pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA);
1095 				pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB);
1096 				pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC);
1097 				pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE);
1098 				pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG);
1099 				pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF);
1100 
1101 #endif
1102 				//			pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD);
1103 				//			pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD);
1104 				//		pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD);
1105 				//			pNode->onKeyboardPressed.Add(handler, &MyMenuItemHander::onButtonD);
1106 				//			pNode->OnKeyPress
1107 			}
1108 			else
1109 			{
1110 				curNode = tree->AddNode(nodeUText);
1111 				m_internalData->m_nodes.push_back(curNode);
1112 			}
1113 		}
1114 
1115 		if (sCurrentDemo == 0)
1116 		{
1117 			if (firstAvailableDemoIndex >= 0)
1118 			{
1119 				firstNode->SetSelected(true);
1120 				while (firstNode != tree)
1121 				{
1122 					firstNode->ExpandAll();
1123 					firstNode = (Gwen::Controls::TreeNode*)firstNode->GetParent();
1124 				}
1125 
1126 				selectDemo(firstAvailableDemoIndex);
1127 			}
1128 		}
1129 		free(demoNameFromCommandOption);
1130 		demoNameFromCommandOption = 0;
1131 
1132 		btAssert(sCurrentDemo != 0);
1133 		if (sCurrentDemo == 0)
1134 		{
1135 			printf("Error, no demo/example\n");
1136 			exit(0);
1137 		}
1138 
1139 		gui2->registerFileOpenCallback(fileOpenCallback);
1140 		gui2->registerQuitCallback(quitCallback);
1141 	}
1142 
1143 	return true;
1144 }
1145 
getCurrentExample()1146 CommonExampleInterface* OpenGLExampleBrowser::getCurrentExample()
1147 {
1148 	btAssert(sCurrentDemo);
1149 	return sCurrentDemo;
1150 }
1151 
requestedExit()1152 bool OpenGLExampleBrowser::requestedExit()
1153 {
1154 	return s_window->requestedExit();
1155 }
1156 
updateGraphics()1157 void OpenGLExampleBrowser::updateGraphics()
1158 {
1159 	if (sCurrentDemo)
1160 	{
1161 		if (!pauseSimulation || singleStepSimulation)
1162 		{
1163 			//B3_PROFILE("sCurrentDemo->updateGraphics");
1164 			sCurrentDemo->updateGraphics();
1165 		}
1166 	}
1167 }
1168 
update(float deltaTime)1169 void OpenGLExampleBrowser::update(float deltaTime)
1170 {
1171 
1172 	b3ChromeUtilsEnableProfiling();
1173 
1174 	if (!gEnableRenderLoop && !singleStepSimulation)
1175 	{
1176 		B3_PROFILE("updateGraphics");
1177 		sCurrentDemo->updateGraphics();
1178 		return;
1179 	}
1180 
1181 	B3_PROFILE("OpenGLExampleBrowser::update");
1182 	//assert(glGetError() == GL_NO_ERROR);
1183 	{
1184 		B3_PROFILE("s_instancingRenderer");
1185 		s_instancingRenderer->init();
1186 	}
1187 	DrawGridData dg;
1188 	dg.upAxis = s_app->getUpAxis();
1189 
1190 	{
1191 		BT_PROFILE("Update Camera and Light");
1192 
1193 		s_instancingRenderer->updateCamera(dg.upAxis);
1194 	}
1195 
1196 	static int frameCount = 0;
1197 	frameCount++;
1198 
1199 	if (0)
1200 	{
1201 		BT_PROFILE("Draw frame counter");
1202 		char bla[1024];
1203 		sprintf(bla, "Frame %d", frameCount);
1204 		s_app->drawText(bla, 10, 10);
1205 	}
1206 
1207 	if (gPngFileName)
1208 	{
1209 		static int skip = 0;
1210 		skip--;
1211 		if (skip < 0)
1212 		{
1213 			skip = gPngSkipFrames;
1214 			//printf("gPngFileName=%s\n",gPngFileName);
1215 			static int s_frameCount = 0;
1216 
1217 			sprintf(staticPngFileName, "%s%d.png", gPngFileName, s_frameCount++);
1218 			//b3Printf("Made screenshot %s",staticPngFileName);
1219 			s_app->dumpNextFrameToPng(staticPngFileName);
1220 			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1221 		}
1222 	}
1223 
1224 	if (sCurrentDemo)
1225 	{
1226 		if (!pauseSimulation || singleStepSimulation)
1227 		{
1228 			//printf("---------------------------------------------------\n");
1229 			//printf("Framecount = %d\n",frameCount);
1230 			B3_PROFILE("sCurrentDemo->stepSimulation");
1231 
1232 			if (gFixedTimeStep > 0)
1233 			{
1234 
1235 				sCurrentDemo->stepSimulation(gFixedTimeStep);
1236 			}
1237 			else
1238 			{
1239 				sCurrentDemo->stepSimulation(deltaTime);  //1./60.f);
1240 			}
1241 		}
1242 
1243 		if (renderGrid)
1244 		{
1245 			BT_PROFILE("Draw Grid");
1246 			//glPolygonOffset(3.0, 3);
1247 			//glEnable(GL_POLYGON_OFFSET_FILL);
1248 			s_app->drawGrid(dg);
1249 		}
1250 		if (renderVisualGeometry && ((gDebugDrawFlags & btIDebugDraw::DBG_DrawWireframe) == 0))
1251 		{
1252 			if (visualWireframe)
1253 			{
1254 				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1255 			}
1256 			BT_PROFILE("Render Scene");
1257 			sCurrentDemo->renderScene();
1258 		}
1259 		else
1260 		{
1261 			B3_PROFILE("physicsDebugDraw");
1262 			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1263 			sCurrentDemo->physicsDebugDraw(gDebugDrawFlags);
1264 		}
1265 	}
1266 
1267 	{
1268 		if (gui2 && s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera())
1269 		{
1270 			B3_PROFILE("setStatusBarMessage");
1271 			char msg[1024];
1272 			float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance();
1273 			float pitch = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPitch();
1274 			float yaw = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraYaw();
1275 			float camTarget[3];
1276 			float camPos[3];
1277 			s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPosition(camPos);
1278 			s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget);
1279 			sprintf(msg, "camTargetPos=%2.2f,%2.2f,%2.2f, dist=%2.2f, pitch=%2.2f, yaw=%2.2f", camTarget[0], camTarget[1], camTarget[2], camDist, pitch, yaw);
1280 			gui2->setStatusBarMessage(msg, true);
1281 		}
1282 	}
1283 
1284 	static int toggle = 1;
1285 	if (renderGui)
1286 	{
1287 		B3_PROFILE("renderGui");
1288 #ifndef BT_NO_PROFILE
1289 
1290 		if (!pauseSimulation || singleStepSimulation)
1291 		{
1292 			if (isProfileWindowVisible(s_profWindow))
1293 			{
1294 				processProfileData(s_profWindow, false);
1295 			}
1296 		}
1297 #endif  //#ifndef BT_NO_PROFILE
1298 
1299 		{
1300 			B3_PROFILE("updateOpenGL");
1301 			if (sUseOpenGL2)
1302 			{
1303 				saveOpenGLState(s_instancingRenderer->getScreenWidth() * s_window->getRetinaScale(), s_instancingRenderer->getScreenHeight() * s_window->getRetinaScale());
1304 			}
1305 
1306 			if (m_internalData->m_gui)
1307 			{
1308 				gBlockGuiMessages = true;
1309 				m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
1310 
1311 				gBlockGuiMessages = false;
1312 			}
1313 
1314 			if (sUseOpenGL2)
1315 			{
1316 				restoreOpenGLState();
1317 			}
1318 		}
1319 	}
1320 
1321 	singleStepSimulation = false;
1322 
1323 	toggle = 1 - toggle;
1324 	{
1325 		BT_PROFILE("Sync Parameters");
1326 		if (s_parameterInterface)
1327 		{
1328 			s_parameterInterface->syncParameters();
1329 		}
1330 	}
1331 	{
1332 		BT_PROFILE("Swap Buffers");
1333 		s_app->swapBuffer();
1334 	}
1335 
1336 	if (gui2)
1337 	{
1338 		B3_PROFILE("forceUpdateScrollBars");
1339 		gui2->forceUpdateScrollBars();
1340 	}
1341 }
1342 
setSharedMemoryInterface(class SharedMemoryInterface * sharedMem)1343 void OpenGLExampleBrowser::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
1344 {
1345 	gDisableDemoSelection = true;
1346 	sSharedMem = sharedMem;
1347 }
1348