EGL review. EGL dynamic loading, windowType to int moved to glad2 Require GL 3.3 as GLInstancingRenderer.cpp uses glVertexAttribDivisor glad2 update with dynamic X11 added removed old file build fix fix mac/win EGL w/o c++11, off by default fix premake fixup: premake fix 2
1414 lines
33 KiB
C++
1414 lines
33 KiB
C++
#include "OpenGLExampleBrowser.h"
|
|
#include "LinearMath/btQuickprof.h"
|
|
#include "../OpenGLWindow/OpenGLInclude.h"
|
|
#include "../OpenGLWindow/SimpleOpenGL2App.h"
|
|
#ifndef NO_OPENGL3
|
|
#include "../OpenGLWindow/SimpleOpenGL3App.h"
|
|
#endif
|
|
#include "../CommonInterfaces/CommonRenderInterface.h"
|
|
#ifdef __APPLE__
|
|
#include "../OpenGLWindow/MacOpenGLWindow.h"
|
|
#else
|
|
#ifdef _WIN32
|
|
#include "../OpenGLWindow/Win32OpenGLWindow.h"
|
|
#else
|
|
//let's cross the fingers it is Linux/X11
|
|
#ifdef BT_USE_EGL
|
|
#include "../OpenGLWindow/EGLOpenGLWindow.h"
|
|
#else
|
|
#include "../OpenGLWindow/X11OpenGLWindow.h"
|
|
#endif //BT_USE_EGL
|
|
#endif //_WIN32
|
|
#endif//__APPLE__
|
|
#include "../ThirdPartyLibs/Gwen/Renderers/OpenGL_DebugFont.h"
|
|
#include "LinearMath/btThreads.h"
|
|
#include "Bullet3Common/b3Vector3.h"
|
|
#include "assert.h"
|
|
#include <stdio.h>
|
|
#include "GwenGUISupport/gwenInternalData.h"
|
|
#include "GwenGUISupport/gwenUserInterface.h"
|
|
#include "../Utils/b3Clock.h"
|
|
#include "../Utils/ChromeTraceUtil.h"
|
|
#include "GwenGUISupport/GwenParameterInterface.h"
|
|
#ifndef BT_NO_PROFILE
|
|
#include "GwenGUISupport/GwenProfileWindow.h"
|
|
#endif
|
|
#include "GwenGUISupport/GwenTextureWindow.h"
|
|
#include "GwenGUISupport/GraphingTexture.h"
|
|
#include "../CommonInterfaces/Common2dCanvasInterface.h"
|
|
#include "../CommonInterfaces/CommonExampleInterface.h"
|
|
#include "Bullet3Common/b3CommandLineArgs.h"
|
|
#include "../OpenGLWindow/SimpleCamera.h"
|
|
#include "../OpenGLWindow/SimpleOpenGL2Renderer.h"
|
|
#include "ExampleEntries.h"
|
|
#include "OpenGLGuiHelper.h"
|
|
#include "Bullet3Common/b3FileUtils.h"
|
|
|
|
#include "LinearMath/btIDebugDraw.h"
|
|
//quick test for file import, @todo(erwincoumans) make it more general and add other file formats
|
|
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
|
|
#include "../Importers/ImportBullet/SerializeSetup.h"
|
|
#include "Bullet3Common/b3HashMap.h"
|
|
|
|
struct GL3TexLoader : public MyTextureLoader
|
|
{
|
|
b3HashMap<b3HashString, GLint> m_hashMap;
|
|
|
|
virtual void LoadTexture(Gwen::Texture* pTexture)
|
|
{
|
|
Gwen::String namestr = pTexture->name.Get();
|
|
const char* n = namestr.c_str();
|
|
GLint* texIdPtr = m_hashMap[n];
|
|
if (texIdPtr)
|
|
{
|
|
pTexture->m_intData = *texIdPtr;
|
|
}
|
|
}
|
|
virtual void FreeTexture(Gwen::Texture* pTexture)
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
struct OpenGLExampleBrowserInternalData
|
|
{
|
|
Gwen::Renderer::Base* m_gwenRenderer;
|
|
CommonGraphicsApp* m_app;
|
|
#ifndef BT_NO_PROFILE
|
|
MyProfileWindow* m_profWindow;
|
|
#endif //BT_NO_PROFILE
|
|
btAlignedObjectArray<Gwen::Controls::TreeNode*> m_nodes;
|
|
GwenUserInterface* m_gui;
|
|
GL3TexLoader* m_myTexLoader;
|
|
struct MyMenuItemHander* m_handler2;
|
|
btAlignedObjectArray<MyMenuItemHander*> m_handlers;
|
|
|
|
OpenGLExampleBrowserInternalData()
|
|
: m_gwenRenderer(0),
|
|
m_app(0),
|
|
// m_profWindow(0),
|
|
m_gui(0),
|
|
m_myTexLoader(0),
|
|
m_handler2(0)
|
|
{
|
|
|
|
}
|
|
};
|
|
|
|
static CommonGraphicsApp* s_app=0;
|
|
|
|
static CommonWindowInterface* s_window = 0;
|
|
static CommonParameterInterface* s_parameterInterface=0;
|
|
static CommonRenderInterface* s_instancingRenderer=0;
|
|
static OpenGLGuiHelper* s_guiHelper=0;
|
|
#ifndef BT_NO_PROFILE
|
|
static MyProfileWindow* s_profWindow =0;
|
|
#endif //BT_NO_PROFILE
|
|
static SharedMemoryInterface* sSharedMem = 0;
|
|
|
|
#define DEMO_SELECTION_COMBOBOX 13
|
|
const char* startFileName = "0_Bullet3Demo.txt";
|
|
char staticPngFileName[1024];
|
|
//static GwenUserInterface* gui = 0;
|
|
static GwenUserInterface* gui2 = 0;
|
|
static int sCurrentDemoIndex = -1;
|
|
static int sCurrentHightlighted = 0;
|
|
static CommonExampleInterface* sCurrentDemo = 0;
|
|
static b3AlignedObjectArray<const char*> allNames;
|
|
static float gFixedTimeStep = 0;
|
|
bool gAllowRetina = true;
|
|
bool gDisableDemoSelection = false;
|
|
int gRenderDevice = -1;
|
|
int gWindowBackend = 0;
|
|
static class ExampleEntries* gAllExamples=0;
|
|
bool sUseOpenGL2 = false;
|
|
#ifndef USE_OPENGL3
|
|
extern bool useShadowMap;
|
|
#endif
|
|
|
|
bool visualWireframe=false;
|
|
static bool renderVisualGeometry=true;
|
|
static bool renderGrid = true;
|
|
static bool gEnableRenderLoop = true;
|
|
|
|
bool renderGui = true;
|
|
static bool enable_experimental_opencl = false;
|
|
|
|
static bool gEnableDefaultKeyboardShortcuts = true;
|
|
static bool gEnableDefaultMousePicking = true;
|
|
|
|
|
|
int gDebugDrawFlags = 0;
|
|
static bool pauseSimulation=false;
|
|
static bool singleStepSimulation = false;
|
|
int midiBaseIndex = 176;
|
|
extern bool gDisableDeactivation;
|
|
|
|
int gSharedMemoryKey=-1;
|
|
|
|
|
|
///some quick test variable for the OpenCL examples
|
|
|
|
int gPreferredOpenCLDeviceIndex=-1;
|
|
int gPreferredOpenCLPlatformIndex=-1;
|
|
int gGpuArraySizeX=45;
|
|
int gGpuArraySizeY=55;
|
|
int gGpuArraySizeZ=45;
|
|
|
|
//#include <float.h>
|
|
//unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);
|
|
|
|
|
|
|
|
void deleteDemo()
|
|
{
|
|
if (sCurrentDemo)
|
|
{
|
|
sCurrentDemo->exitPhysics();
|
|
s_instancingRenderer->removeAllInstances();
|
|
delete sCurrentDemo;
|
|
sCurrentDemo=0;
|
|
delete s_guiHelper;
|
|
s_guiHelper = 0;
|
|
|
|
// CProfileManager::CleanupMemory();
|
|
}
|
|
}
|
|
|
|
const char* gPngFileName = 0;
|
|
int gPngSkipFrames = 0;
|
|
|
|
|
|
|
|
|
|
b3KeyboardCallback prevKeyboardCallback = 0;
|
|
|
|
void MyKeyboardCallback(int key, int state)
|
|
{
|
|
|
|
//b3Printf("key=%d, state=%d", key, state);
|
|
bool handled = false;
|
|
if (renderGui)
|
|
{
|
|
if (gui2 && !handled )
|
|
{
|
|
handled = gui2->keyboardCallback(key, state);
|
|
}
|
|
}
|
|
|
|
if (!handled && sCurrentDemo)
|
|
{
|
|
handled = sCurrentDemo->keyboardCallback(key,state);
|
|
}
|
|
|
|
|
|
|
|
|
|
//checkout: is it desired to ignore keys, if the demo already handles them?
|
|
//if (handled)
|
|
// return;
|
|
|
|
if (gEnableDefaultKeyboardShortcuts)
|
|
{
|
|
if (key=='a' && state)
|
|
{
|
|
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawAabb;
|
|
}
|
|
if (key=='c' && state)
|
|
{
|
|
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawContactPoints;
|
|
}
|
|
if (key == 'd' && state)
|
|
{
|
|
gDebugDrawFlags ^= btIDebugDraw::DBG_NoDeactivation;
|
|
gDisableDeactivation = ((gDebugDrawFlags & btIDebugDraw::DBG_NoDeactivation) != 0);
|
|
}
|
|
if (key == 'j' && state)
|
|
{
|
|
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawFrames;
|
|
}
|
|
|
|
if (key == 'k' && state)
|
|
{
|
|
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraints;
|
|
}
|
|
|
|
if (key=='l' && state)
|
|
{
|
|
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraintLimits;
|
|
}
|
|
if (key=='w' && state)
|
|
{
|
|
visualWireframe=!visualWireframe;
|
|
gDebugDrawFlags ^= btIDebugDraw::DBG_DrawWireframe;
|
|
}
|
|
|
|
|
|
if (key=='v' && state)
|
|
{
|
|
renderVisualGeometry = !renderVisualGeometry;
|
|
}
|
|
if (key=='g' && state)
|
|
{
|
|
renderGrid = !renderGrid;
|
|
renderGui = !renderGui;
|
|
}
|
|
|
|
|
|
if (key=='i' && state)
|
|
{
|
|
pauseSimulation = !pauseSimulation;
|
|
}
|
|
if (key == 'o' && state)
|
|
{
|
|
singleStepSimulation = true;
|
|
}
|
|
|
|
if (key=='p')
|
|
{
|
|
#ifndef BT_NO_PROFILE
|
|
if (state)
|
|
{
|
|
b3ChromeUtilsStartTimings();
|
|
|
|
} else
|
|
{
|
|
b3ChromeUtilsStopTimingsAndWriteJsonFile("timings");
|
|
}
|
|
#endif //BT_NO_PROFILE
|
|
}
|
|
|
|
#ifndef NO_OPENGL3
|
|
if (key=='s' && state)
|
|
{
|
|
useShadowMap=!useShadowMap;
|
|
}
|
|
#endif
|
|
if (key==B3G_F1)
|
|
{
|
|
static int count=0;
|
|
if (state)
|
|
{
|
|
b3Printf("F1 pressed %d", count++);
|
|
|
|
if (gPngFileName)
|
|
{
|
|
b3Printf("disable image dump");
|
|
|
|
gPngFileName=0;
|
|
} else
|
|
{
|
|
gPngFileName = gAllExamples->getExampleName(sCurrentDemoIndex);
|
|
b3Printf("enable image dump %s",gPngFileName);
|
|
|
|
}
|
|
} else
|
|
{
|
|
b3Printf("F1 released %d",count++);
|
|
}
|
|
}
|
|
}
|
|
if (key==B3G_ESCAPE && s_window)
|
|
{
|
|
|
|
s_window->setRequestExit();
|
|
}
|
|
|
|
if (prevKeyboardCallback)
|
|
prevKeyboardCallback(key,state);
|
|
}
|
|
|
|
|
|
b3MouseMoveCallback prevMouseMoveCallback = 0;
|
|
static void MyMouseMoveCallback( float x, float y)
|
|
{
|
|
bool handled = false;
|
|
if (sCurrentDemo)
|
|
handled = sCurrentDemo->mouseMoveCallback(x,y);
|
|
if (renderGui)
|
|
{
|
|
if (!handled && gui2)
|
|
handled = gui2->mouseMoveCallback(x,y);
|
|
}
|
|
if (!handled)
|
|
{
|
|
if (prevMouseMoveCallback)
|
|
prevMouseMoveCallback(x,y);
|
|
}
|
|
}
|
|
|
|
b3MouseButtonCallback prevMouseButtonCallback = 0;
|
|
|
|
static void MyMouseButtonCallback(int button, int state, float x, float y)
|
|
{
|
|
bool handled = false;
|
|
//try picking first
|
|
if (sCurrentDemo)
|
|
handled = sCurrentDemo->mouseButtonCallback(button,state,x,y);
|
|
|
|
if (renderGui)
|
|
{
|
|
if (!handled && gui2)
|
|
handled = gui2->mouseButtonCallback(button,state,x,y);
|
|
}
|
|
if (!handled)
|
|
{
|
|
if (prevMouseButtonCallback )
|
|
prevMouseButtonCallback (button,state,x,y);
|
|
}
|
|
// b3DefaultMouseButtonCallback(button,state,x,y);
|
|
}
|
|
|
|
#include <string.h>
|
|
struct FileImporterByExtension
|
|
{
|
|
std::string m_extension;
|
|
CommonExampleInterface::CreateFunc* m_createFunc;
|
|
};
|
|
|
|
static btAlignedObjectArray<FileImporterByExtension> gFileImporterByExtension;
|
|
|
|
void OpenGLExampleBrowser::registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc)
|
|
{
|
|
FileImporterByExtension fi;
|
|
fi.m_extension = extension;
|
|
fi.m_createFunc = createFunc;
|
|
gFileImporterByExtension.push_back(fi);
|
|
}
|
|
#include "../SharedMemory/SharedMemoryPublic.h"
|
|
|
|
void OpenGLExampleBrowserVisualizerFlagCallback(int flag, bool enable)
|
|
{
|
|
if (flag == COV_ENABLE_Y_AXIS_UP)
|
|
{
|
|
//either Y = up or Z
|
|
int upAxis = enable? 1:2;
|
|
s_app->setUpAxis(upAxis);
|
|
}
|
|
|
|
if (flag == COV_ENABLE_RENDERING)
|
|
{
|
|
gEnableRenderLoop = (enable!=0);
|
|
}
|
|
if (flag == COV_ENABLE_SHADOWS)
|
|
{
|
|
useShadowMap = enable;
|
|
}
|
|
if (flag == COV_ENABLE_GUI)
|
|
{
|
|
renderGui = enable;
|
|
renderGrid = enable;
|
|
}
|
|
|
|
if (flag == COV_ENABLE_KEYBOARD_SHORTCUTS)
|
|
{
|
|
gEnableDefaultKeyboardShortcuts = enable;
|
|
}
|
|
if (flag == COV_ENABLE_MOUSE_PICKING)
|
|
{
|
|
gEnableDefaultMousePicking = enable;
|
|
}
|
|
|
|
if (flag == COV_ENABLE_WIREFRAME)
|
|
{
|
|
visualWireframe = enable;
|
|
if (visualWireframe)
|
|
{
|
|
gDebugDrawFlags |= btIDebugDraw::DBG_DrawWireframe;
|
|
}
|
|
else
|
|
{
|
|
gDebugDrawFlags &= ~btIDebugDraw::DBG_DrawWireframe;
|
|
}
|
|
}
|
|
}
|
|
|
|
void openFileDemo(const char* filename)
|
|
{
|
|
|
|
deleteDemo();
|
|
|
|
s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
|
|
s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback);
|
|
|
|
s_parameterInterface->removeAllParameters();
|
|
|
|
|
|
CommonExampleOptions options(s_guiHelper,1);
|
|
options.m_fileName = filename;
|
|
char fullPath[1024];
|
|
sprintf(fullPath, "%s", filename);
|
|
b3FileUtils::toLower(fullPath);
|
|
|
|
for (int i=0;i<gFileImporterByExtension.size();i++)
|
|
{
|
|
if (strstr(fullPath, gFileImporterByExtension[i].m_extension.c_str()))
|
|
{
|
|
sCurrentDemo = gFileImporterByExtension[i].m_createFunc(options);
|
|
}
|
|
}
|
|
|
|
|
|
if (sCurrentDemo)
|
|
{
|
|
sCurrentDemo->initPhysics();
|
|
sCurrentDemo->resetCamera();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void selectDemo(int demoIndex)
|
|
{
|
|
bool resetCamera = (sCurrentDemoIndex != demoIndex);
|
|
sCurrentDemoIndex = demoIndex;
|
|
sCurrentHightlighted = demoIndex;
|
|
int numDemos = gAllExamples->getNumRegisteredExamples();
|
|
|
|
|
|
|
|
if (demoIndex>numDemos)
|
|
{
|
|
demoIndex = 0;
|
|
}
|
|
deleteDemo();
|
|
|
|
|
|
CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex);
|
|
if (func)
|
|
{
|
|
if (s_parameterInterface)
|
|
{
|
|
s_parameterInterface->removeAllParameters();
|
|
}
|
|
int option = gAllExamples->getExampleOption(demoIndex);
|
|
s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
|
|
s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback);
|
|
|
|
CommonExampleOptions options(s_guiHelper, option);
|
|
options.m_sharedMem = sSharedMem;
|
|
sCurrentDemo = (*func)(options);
|
|
if (sCurrentDemo)
|
|
{
|
|
if (gui2)
|
|
{
|
|
gui2->setStatusBarMessage("Status: OK", false);
|
|
}
|
|
b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex));
|
|
if (gui2)
|
|
{
|
|
gui2->setExampleDescription(gAllExamples->getExampleDescription(demoIndex));
|
|
}
|
|
|
|
sCurrentDemo->initPhysics();
|
|
if(resetCamera)
|
|
{
|
|
sCurrentDemo->resetCamera();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
static void saveCurrentSettings(int currentEntry,const char* startFileName)
|
|
{
|
|
FILE* f = fopen(startFileName,"w");
|
|
if (f)
|
|
{
|
|
fprintf(f,"--start_demo_name=%s\n", gAllExamples->getExampleName(sCurrentDemoIndex));
|
|
fprintf(f,"--mouse_move_multiplier=%f\n", s_app->getMouseMoveMultiplier());
|
|
fprintf(f,"--mouse_wheel_multiplier=%f\n", s_app->getMouseWheelMultiplier());
|
|
float red,green,blue;
|
|
s_app->getBackgroundColor(&red,&green,&blue);
|
|
fprintf(f,"--background_color_red= %f\n", red);
|
|
fprintf(f,"--background_color_green= %f\n", green);
|
|
fprintf(f,"--background_color_blue= %f\n", blue);
|
|
fprintf(f,"--fixed_timestep= %f\n", gFixedTimeStep);
|
|
if (!gAllowRetina)
|
|
{
|
|
fprintf(f,"--disable_retina");
|
|
}
|
|
|
|
if (enable_experimental_opencl)
|
|
{
|
|
fprintf(f,"--enable_experimental_opencl\n");
|
|
}
|
|
// if (sUseOpenGL2 )
|
|
// {
|
|
// fprintf(f,"--opengl2\n");
|
|
// }
|
|
|
|
fclose(f);
|
|
}
|
|
};
|
|
|
|
static void loadCurrentSettings(const char* startFileName, b3CommandLineArgs& args)
|
|
{
|
|
//int currentEntry= 0;
|
|
FILE* f = fopen(startFileName,"r");
|
|
if (f)
|
|
{
|
|
char oneline[1024];
|
|
char* argv[] = {0,&oneline[0]};
|
|
|
|
while( fgets (oneline, 1024, f)!=NULL )
|
|
{
|
|
char *pos;
|
|
if ((pos=strchr(oneline, '\n')) != NULL)
|
|
*pos = '\0';
|
|
args.addArgs(2,argv);
|
|
}
|
|
fclose(f);
|
|
}
|
|
|
|
};
|
|
|
|
void MyComboBoxCallback(int comboId, const char* item)
|
|
{
|
|
//printf("comboId = %d, item = %s\n",comboId, item);
|
|
if (comboId==DEMO_SELECTION_COMBOBOX)
|
|
{
|
|
//find selected item
|
|
for (int i=0;i<allNames.size();i++)
|
|
{
|
|
if (strcmp(item,allNames[i])==0)
|
|
{
|
|
selectDemo(i);
|
|
saveCurrentSettings(sCurrentDemoIndex,startFileName);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//in case of multi-threading, don't submit messages while the GUI is rendering (causing crashes)
|
|
static bool gBlockGuiMessages = false;
|
|
|
|
void MyGuiPrintf(const char* msg)
|
|
{
|
|
printf("b3Printf: %s\n",msg);
|
|
if (!gDisableDemoSelection && !gBlockGuiMessages)
|
|
{
|
|
gui2->textOutput(msg);
|
|
gui2->forceUpdateScrollBars();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void MyStatusBarPrintf(const char* msg)
|
|
{
|
|
printf("b3Printf: %s\n", msg);
|
|
if (!gDisableDemoSelection && !gBlockGuiMessages)
|
|
{
|
|
bool isLeft = true;
|
|
gui2->setStatusBarMessage(msg,isLeft);
|
|
}
|
|
}
|
|
|
|
|
|
void MyStatusBarError(const char* msg)
|
|
{
|
|
printf("Warning: %s\n", msg);
|
|
if (!gDisableDemoSelection && !gBlockGuiMessages)
|
|
{
|
|
bool isLeft = false;
|
|
gui2->setStatusBarMessage(msg,isLeft);
|
|
gui2->textOutput(msg);
|
|
gui2->forceUpdateScrollBars();
|
|
}
|
|
btAssert(0);
|
|
|
|
}
|
|
|
|
struct MyMenuItemHander :public Gwen::Event::Handler
|
|
{
|
|
int m_buttonId;
|
|
|
|
MyMenuItemHander( int buttonId)
|
|
:m_buttonId(buttonId)
|
|
{
|
|
}
|
|
|
|
void onButtonA(Gwen::Controls::Base* pControl)
|
|
{
|
|
//const Gwen::String& name = pControl->GetName();
|
|
Gwen::Controls::TreeNode* node = (Gwen::Controls::TreeNode*)pControl;
|
|
// Gwen::Controls::Label* l = node->GetButton();
|
|
|
|
Gwen::UnicodeString la = node->GetButton()->GetText();// node->GetButton()->GetName();// GetText();
|
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
|
// const char* ha = laa.c_str();
|
|
|
|
//printf("selected %s\n", ha);
|
|
//int dep = but->IsDepressed();
|
|
//int tog = but->GetToggleState();
|
|
// if (m_data->m_toggleButtonCallback)
|
|
// (*m_data->m_toggleButtonCallback)(m_buttonId, tog);
|
|
}
|
|
void onButtonB(Gwen::Controls::Base* pControl)
|
|
{
|
|
Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
|
Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
|
//const char* ha = laa.c_str();
|
|
|
|
if (!gDisableDemoSelection )
|
|
{
|
|
selectDemo(sCurrentHightlighted);
|
|
saveCurrentSettings(sCurrentDemoIndex, startFileName);
|
|
}
|
|
}
|
|
void onButtonC(Gwen::Controls::Base* pControl)
|
|
{
|
|
/*Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
|
Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
|
const char* ha = laa.c_str();
|
|
|
|
|
|
printf("onButtonC ! %s\n", ha);
|
|
*/
|
|
}
|
|
void onButtonD(Gwen::Controls::Base* pControl)
|
|
{
|
|
/* Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl;
|
|
Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText();
|
|
Gwen::String laa = Gwen::Utility::UnicodeToString(la);
|
|
const char* ha = laa.c_str();
|
|
*/
|
|
|
|
// printf("onKeyReturn ! \n");
|
|
if (!gDisableDemoSelection )
|
|
{
|
|
selectDemo(sCurrentHightlighted);
|
|
saveCurrentSettings(sCurrentDemoIndex, startFileName);
|
|
}
|
|
|
|
}
|
|
|
|
void onButtonE(Gwen::Controls::Base* pControl)
|
|
{
|
|
// printf("select %d\n",m_buttonId);
|
|
sCurrentHightlighted = m_buttonId;
|
|
gui2->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted));
|
|
}
|
|
|
|
void onButtonF(Gwen::Controls::Base* pControl)
|
|
{
|
|
//printf("selection changed!\n");
|
|
}
|
|
|
|
void onButtonG(Gwen::Controls::Base* pControl)
|
|
{
|
|
//printf("onButtonG !\n");
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
void quitCallback()
|
|
{
|
|
|
|
s_window->setRequestExit();
|
|
}
|
|
|
|
void fileOpenCallback()
|
|
{
|
|
|
|
char filename[1024];
|
|
int len = s_window->fileOpenDialog(filename,1024);
|
|
if (len)
|
|
{
|
|
//todo(erwincoumans) check if it is actually URDF
|
|
//printf("file open:%s\n", filename);
|
|
openFileDemo(filename);
|
|
}
|
|
}
|
|
|
|
#define MAX_GRAPH_WINDOWS 5
|
|
|
|
struct QuickCanvas : public Common2dCanvasInterface
|
|
{
|
|
GL3TexLoader* m_myTexLoader;
|
|
|
|
MyGraphWindow* m_gw[MAX_GRAPH_WINDOWS];
|
|
GraphingTexture* m_gt[MAX_GRAPH_WINDOWS];
|
|
int m_curNumGraphWindows;
|
|
|
|
|
|
QuickCanvas(GL3TexLoader* myTexLoader)
|
|
:m_myTexLoader(myTexLoader),
|
|
m_curNumGraphWindows(0)
|
|
{
|
|
for (int i=0;i<MAX_GRAPH_WINDOWS;i++)
|
|
{
|
|
m_gw[i] = 0;
|
|
m_gt[i] = 0;
|
|
}
|
|
}
|
|
virtual ~QuickCanvas() {}
|
|
virtual int createCanvas(const char* canvasName, int width, int height, int xPos, int yPos)
|
|
{
|
|
if (m_curNumGraphWindows<MAX_GRAPH_WINDOWS)
|
|
{
|
|
//find a slot
|
|
int slot = m_curNumGraphWindows;
|
|
btAssert(slot<MAX_GRAPH_WINDOWS);
|
|
if (slot>=MAX_GRAPH_WINDOWS)
|
|
return 0;//don't crash
|
|
|
|
m_curNumGraphWindows++;
|
|
|
|
MyGraphInput input(gui2->getInternalData());
|
|
input.m_width=width;
|
|
input.m_height=height;
|
|
input.m_xPos = xPos;
|
|
input.m_yPos = yPos;
|
|
input.m_name=canvasName;
|
|
input.m_texName = canvasName;
|
|
m_gt[slot] = new GraphingTexture;
|
|
m_gt[slot]->create(width,height);
|
|
int texId = m_gt[slot]->getTextureId();
|
|
m_myTexLoader->m_hashMap.insert(canvasName, texId);
|
|
m_gw[slot] = setupTextureWindow(input);
|
|
|
|
return slot;
|
|
}
|
|
return -1;
|
|
}
|
|
virtual void destroyCanvas(int canvasId)
|
|
{
|
|
btAssert(canvasId>=0);
|
|
delete m_gt[canvasId];
|
|
m_gt[canvasId] = 0;
|
|
destroyTextureWindow(m_gw[canvasId]);
|
|
m_gw[canvasId] = 0;
|
|
m_curNumGraphWindows--;
|
|
}
|
|
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)
|
|
{
|
|
btAssert(canvasId>=0);
|
|
btAssert(canvasId<m_curNumGraphWindows);
|
|
m_gt[canvasId]->setPixel(x,y,red,green,blue,alpha);
|
|
}
|
|
|
|
virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green,unsigned char& blue, unsigned char& alpha)
|
|
{
|
|
btAssert(canvasId>=0);
|
|
btAssert(canvasId<m_curNumGraphWindows);
|
|
m_gt[canvasId]->getPixel(x,y,red,green,blue,alpha);
|
|
}
|
|
|
|
virtual void refreshImageData(int canvasId)
|
|
{
|
|
m_gt[canvasId]->uploadImageData();
|
|
}
|
|
};
|
|
|
|
|
|
OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples)
|
|
{
|
|
m_internalData = new OpenGLExampleBrowserInternalData;
|
|
|
|
gAllExamples = examples;
|
|
}
|
|
|
|
OpenGLExampleBrowser::~OpenGLExampleBrowser()
|
|
{
|
|
deleteDemo();
|
|
for (int i = 0; i < m_internalData->m_nodes.size(); i++)
|
|
{
|
|
delete m_internalData->m_nodes[i];
|
|
}
|
|
delete m_internalData->m_handler2;
|
|
for (int i = 0; i < m_internalData->m_handlers.size(); i++)
|
|
{
|
|
delete m_internalData->m_handlers[i];
|
|
}
|
|
m_internalData->m_handlers.clear();
|
|
m_internalData->m_nodes.clear();
|
|
delete s_parameterInterface;
|
|
s_parameterInterface = 0;
|
|
delete s_app->m_2dCanvasInterface;
|
|
s_app->m_2dCanvasInterface = 0;
|
|
|
|
#ifndef BT_NO_PROFILE
|
|
destroyProfileWindow(m_internalData->m_profWindow);
|
|
#endif
|
|
|
|
m_internalData->m_gui->exit();
|
|
|
|
|
|
|
|
|
|
delete m_internalData->m_gui;
|
|
delete m_internalData->m_gwenRenderer;
|
|
delete m_internalData->m_myTexLoader;
|
|
|
|
|
|
|
|
|
|
|
|
delete m_internalData->m_app;
|
|
s_app = 0;
|
|
|
|
|
|
|
|
|
|
|
|
delete m_internalData;
|
|
|
|
gFileImporterByExtension.clear();
|
|
gAllExamples = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "EmptyExample.h"
|
|
|
|
bool OpenGLExampleBrowser::init(int argc, char* argv[])
|
|
{
|
|
b3CommandLineArgs args(argc,argv);
|
|
|
|
loadCurrentSettings(startFileName, args);
|
|
if (args.CheckCmdLineFlag("nogui"))
|
|
{
|
|
renderGrid = false;
|
|
renderGui = false;
|
|
}
|
|
if (args.CheckCmdLineFlag("tracing"))
|
|
{
|
|
b3ChromeUtilsStartTimings();
|
|
}
|
|
args.GetCmdLineArgument("fixed_timestep",gFixedTimeStep);
|
|
args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames);
|
|
///The OpenCL rigid body pipeline is experimental and
|
|
///most OpenCL drivers and OpenCL compilers have issues with our kernels.
|
|
///If you have a high-end desktop GPU such as AMD 7970 or better, or NVIDIA GTX 680 with up-to-date drivers
|
|
///you could give it a try
|
|
///Note that several old OpenCL physics examples still have to be ported over to this new Example Browser
|
|
if (args.CheckCmdLineFlag("enable_experimental_opencl"))
|
|
{
|
|
enable_experimental_opencl = true;
|
|
gAllExamples->initOpenCLExampleEntries();
|
|
}
|
|
|
|
if (args.CheckCmdLineFlag("disable_retina"))
|
|
{
|
|
gAllowRetina = false;
|
|
}
|
|
|
|
|
|
int width = 1024;
|
|
int height=768;
|
|
|
|
if (args.CheckCmdLineFlag("width"))
|
|
{
|
|
args.GetCmdLineArgument("width",width );
|
|
}
|
|
if (args.CheckCmdLineFlag("height"))
|
|
{
|
|
args.GetCmdLineArgument("height",height);
|
|
}
|
|
|
|
#ifndef NO_OPENGL3
|
|
SimpleOpenGL3App* simpleApp=0;
|
|
sUseOpenGL2 = args.CheckCmdLineFlag("opengl2");
|
|
args.GetCmdLineArgument("render_device", gRenderDevice);
|
|
args.GetCmdLineArgument("window_backend", gWindowBackend);
|
|
#else
|
|
sUseOpenGL2 = true;
|
|
#endif
|
|
const char* appTitle = "Bullet Physics ExampleBrowser";
|
|
#if defined (_DEBUG) || defined (DEBUG)
|
|
const char* optMode = "Debug build (slow)";
|
|
#else
|
|
const char* optMode = "Release build";
|
|
#endif
|
|
|
|
#ifdef B3_USE_GLFW
|
|
const char* glContext = "[glfw]";
|
|
#else
|
|
const char* glContext = "[btgl]";
|
|
#endif
|
|
|
|
if (sUseOpenGL2 )
|
|
{
|
|
char title[1024];
|
|
sprintf(title,"%s using limited OpenGL2 fallback %s %s", appTitle,glContext, optMode);
|
|
s_app = new SimpleOpenGL2App(title,width,height);
|
|
s_app->m_renderer = new SimpleOpenGL2Renderer(width,height);
|
|
}
|
|
|
|
#ifndef NO_OPENGL3
|
|
else
|
|
{
|
|
char title[1024];
|
|
sprintf(title,"%s using OpenGL3+ %s %s", appTitle,glContext, optMode);
|
|
simpleApp = new SimpleOpenGL3App(title,width,height, gAllowRetina, gWindowBackend, gRenderDevice);
|
|
s_app = simpleApp;
|
|
}
|
|
#endif
|
|
m_internalData->m_app = s_app;
|
|
char* gVideoFileName = 0;
|
|
args.GetCmdLineArgument("mp4",gVideoFileName);
|
|
#ifndef NO_OPENGL3
|
|
if (gVideoFileName)
|
|
simpleApp->dumpFramesToVideo(gVideoFileName);
|
|
#endif
|
|
|
|
s_instancingRenderer = s_app->m_renderer;
|
|
s_window = s_app->m_window;
|
|
|
|
width = s_window->getWidth();
|
|
height = s_window->getHeight();
|
|
|
|
prevMouseMoveCallback = s_window->getMouseMoveCallback();
|
|
s_window->setMouseMoveCallback(MyMouseMoveCallback);
|
|
|
|
prevMouseButtonCallback = s_window->getMouseButtonCallback();
|
|
s_window->setMouseButtonCallback(MyMouseButtonCallback);
|
|
prevKeyboardCallback = s_window->getKeyboardCallback();
|
|
s_window->setKeyboardCallback(MyKeyboardCallback);
|
|
|
|
s_app->m_renderer->getActiveCamera()->setCameraDistance(13);
|
|
s_app->m_renderer->getActiveCamera()->setCameraPitch(0);
|
|
s_app->m_renderer->getActiveCamera()->setCameraTargetPosition(0,0,0);
|
|
|
|
float mouseMoveMult= s_app->getMouseMoveMultiplier();
|
|
if (args.GetCmdLineArgument("mouse_move_multiplier", mouseMoveMult))
|
|
{
|
|
s_app->setMouseMoveMultiplier(mouseMoveMult);
|
|
}
|
|
|
|
|
|
float mouseWheelMult= s_app->getMouseWheelMultiplier();
|
|
if (args.GetCmdLineArgument("mouse_wheel_multiplier",mouseWheelMult))
|
|
{
|
|
s_app->setMouseWheelMultiplier(mouseWheelMult);
|
|
}
|
|
|
|
|
|
args.GetCmdLineArgument("shared_memory_key", gSharedMemoryKey);
|
|
|
|
float red,green,blue;
|
|
s_app->getBackgroundColor(&red,&green,&blue);
|
|
args.GetCmdLineArgument("background_color_red",red);
|
|
args.GetCmdLineArgument("background_color_green",green);
|
|
args.GetCmdLineArgument("background_color_blue",blue);
|
|
s_app->setBackgroundColor(red,green,blue);
|
|
|
|
b3SetCustomWarningMessageFunc(MyGuiPrintf);
|
|
b3SetCustomPrintfFunc(MyGuiPrintf);
|
|
b3SetCustomErrorMessageFunc(MyStatusBarError);
|
|
|
|
|
|
|
|
assert(glGetError()==GL_NO_ERROR);
|
|
|
|
{
|
|
GL3TexLoader* myTexLoader = new GL3TexLoader;
|
|
m_internalData->m_myTexLoader = myTexLoader;
|
|
|
|
|
|
if (sUseOpenGL2)
|
|
{
|
|
m_internalData->m_gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(s_window->getRetinaScale());
|
|
}
|
|
#ifndef NO_OPENGL3
|
|
else
|
|
{
|
|
sth_stash* fontstash = simpleApp->getFontStash();
|
|
m_internalData->m_gwenRenderer = new GwenOpenGL3CoreRenderer(simpleApp->m_primRenderer, fontstash, width, height, s_window->getRetinaScale(), myTexLoader);
|
|
}
|
|
#endif
|
|
|
|
gui2 = new GwenUserInterface;
|
|
|
|
m_internalData->m_gui = gui2;
|
|
|
|
m_internalData->m_myTexLoader = myTexLoader;
|
|
|
|
|
|
|
|
gui2->init(width, height, m_internalData->m_gwenRenderer, s_window->getRetinaScale());
|
|
|
|
|
|
}
|
|
//gui = 0;// new GwenUserInterface;
|
|
|
|
GL3TexLoader* myTexLoader = m_internalData->m_myTexLoader;
|
|
// = myTexLoader;
|
|
|
|
|
|
|
|
//
|
|
|
|
if (gui2)
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// gui->getInternalData()->m_explorerPage
|
|
Gwen::Controls::TreeControl* tree = gui2->getInternalData()->m_explorerTreeCtrl;
|
|
|
|
|
|
//gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader);
|
|
|
|
#ifndef BT_NO_PROFILE
|
|
s_profWindow= setupProfileWindow(gui2->getInternalData());
|
|
m_internalData->m_profWindow = s_profWindow;
|
|
profileWindowSetVisible(s_profWindow,false);
|
|
#endif //BT_NO_PROFILE
|
|
gui2->setFocus();
|
|
|
|
s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData());
|
|
s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader);
|
|
|
|
|
|
///add some demos to the gAllExamples
|
|
|
|
|
|
int numDemos = gAllExamples->getNumRegisteredExamples();
|
|
|
|
//char nodeText[1024];
|
|
//int curDemo = 0;
|
|
int selectedDemo = 0;
|
|
Gwen::Controls::TreeNode* curNode = tree;
|
|
m_internalData->m_handler2 = new MyMenuItemHander(-1);
|
|
|
|
char* demoNameFromCommandOption = 0;
|
|
args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption);
|
|
if (demoNameFromCommandOption) {
|
|
selectedDemo = -1;
|
|
}
|
|
|
|
tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD);
|
|
int firstAvailableDemoIndex=-1;
|
|
Gwen::Controls::TreeNode* firstNode=0;
|
|
|
|
for (int d = 0; d<numDemos; d++)
|
|
{
|
|
// sprintf(nodeText, "Node %d", i);
|
|
Gwen::UnicodeString nodeUText = Gwen::Utility::StringToUnicode(gAllExamples->getExampleName(d));
|
|
if (gAllExamples->getExampleCreateFunc(d))//was test for gAllExamples[d].m_menuLevel==1
|
|
{
|
|
Gwen::Controls::TreeNode* pNode = curNode->AddNode(nodeUText);
|
|
|
|
if (firstAvailableDemoIndex<0)
|
|
{
|
|
firstAvailableDemoIndex = d;
|
|
firstNode = pNode;
|
|
}
|
|
|
|
if (d == selectedDemo)
|
|
{
|
|
firstAvailableDemoIndex = d;
|
|
firstNode = pNode;
|
|
//pNode->SetSelected(true);
|
|
//tree->ExpandAll();
|
|
// tree->ForceUpdateScrollBars();
|
|
//tree->OnKeyLeft(true);
|
|
// tree->OnKeyRight(true);
|
|
|
|
|
|
//tree->ExpandAll();
|
|
|
|
// selectDemo(d);
|
|
|
|
|
|
}
|
|
|
|
if (demoNameFromCommandOption )
|
|
{
|
|
const char* demoName = gAllExamples->getExampleName(d);
|
|
int res = strcmp(demoName, demoNameFromCommandOption);
|
|
if (res==0)
|
|
{
|
|
firstAvailableDemoIndex = d;
|
|
firstNode = pNode;
|
|
}
|
|
}
|
|
|
|
#if 1
|
|
MyMenuItemHander* handler = new MyMenuItemHander(d);
|
|
m_internalData->m_handlers.push_back(handler);
|
|
|
|
pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA);
|
|
pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB);
|
|
pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC);
|
|
pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE);
|
|
pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG);
|
|
pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF);
|
|
|
|
#endif
|
|
// pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD);
|
|
// pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD);
|
|
// pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD);
|
|
// pNode->onKeyboardPressed.Add(handler, &MyMenuItemHander::onButtonD);
|
|
// pNode->OnKeyPress
|
|
}
|
|
else
|
|
{
|
|
curNode = tree->AddNode(nodeUText);
|
|
m_internalData->m_nodes.push_back(curNode);
|
|
}
|
|
}
|
|
|
|
if (sCurrentDemo==0)
|
|
{
|
|
if (firstAvailableDemoIndex>=0)
|
|
{
|
|
firstNode->SetSelected(true);
|
|
while (firstNode != tree)
|
|
{
|
|
firstNode->ExpandAll();
|
|
firstNode = (Gwen::Controls::TreeNode*)firstNode->GetParent();
|
|
}
|
|
|
|
selectDemo(firstAvailableDemoIndex);
|
|
}
|
|
|
|
}
|
|
free(demoNameFromCommandOption);
|
|
demoNameFromCommandOption = 0;
|
|
|
|
btAssert(sCurrentDemo!=0);
|
|
if (sCurrentDemo==0)
|
|
{
|
|
printf("Error, no demo/example\n");
|
|
exit(0);
|
|
}
|
|
|
|
gui2->registerFileOpenCallback(fileOpenCallback);
|
|
gui2->registerQuitCallback(quitCallback);
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
CommonExampleInterface* OpenGLExampleBrowser::getCurrentExample()
|
|
{
|
|
btAssert(sCurrentDemo);
|
|
return sCurrentDemo;
|
|
}
|
|
|
|
bool OpenGLExampleBrowser::requestedExit()
|
|
{
|
|
return s_window->requestedExit();
|
|
}
|
|
|
|
void OpenGLExampleBrowser::updateGraphics()
|
|
{
|
|
if (sCurrentDemo)
|
|
{
|
|
if (!pauseSimulation || singleStepSimulation)
|
|
{
|
|
//B3_PROFILE("sCurrentDemo->updateGraphics");
|
|
sCurrentDemo->updateGraphics();
|
|
}
|
|
}
|
|
}
|
|
|
|
void OpenGLExampleBrowser::update(float deltaTime)
|
|
{
|
|
b3ChromeUtilsEnableProfiling();
|
|
|
|
if (!gEnableRenderLoop)
|
|
{
|
|
sCurrentDemo->updateGraphics();
|
|
return;
|
|
}
|
|
|
|
B3_PROFILE("OpenGLExampleBrowser::update");
|
|
assert(glGetError()==GL_NO_ERROR);
|
|
s_instancingRenderer->init();
|
|
DrawGridData dg;
|
|
dg.upAxis = s_app->getUpAxis();
|
|
|
|
{
|
|
BT_PROFILE("Update Camera and Light");
|
|
|
|
|
|
|
|
s_instancingRenderer->updateCamera(dg.upAxis);
|
|
}
|
|
|
|
|
|
static int frameCount = 0;
|
|
frameCount++;
|
|
|
|
if (0)
|
|
{
|
|
BT_PROFILE("Draw frame counter");
|
|
char bla[1024];
|
|
sprintf(bla,"Frame %d", frameCount);
|
|
s_app->drawText(bla,10,10);
|
|
}
|
|
|
|
if (gPngFileName)
|
|
{
|
|
|
|
static int skip = 0;
|
|
skip--;
|
|
if (skip<0)
|
|
{
|
|
skip=gPngSkipFrames;
|
|
//printf("gPngFileName=%s\n",gPngFileName);
|
|
static int s_frameCount = 0;
|
|
|
|
sprintf(staticPngFileName,"%s%d.png",gPngFileName,s_frameCount++);
|
|
//b3Printf("Made screenshot %s",staticPngFileName);
|
|
s_app->dumpNextFrameToPng(staticPngFileName);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
}
|
|
|
|
|
|
if (sCurrentDemo)
|
|
{
|
|
if (!pauseSimulation || singleStepSimulation)
|
|
{
|
|
|
|
//printf("---------------------------------------------------\n");
|
|
//printf("Framecount = %d\n",frameCount);
|
|
B3_PROFILE("sCurrentDemo->stepSimulation");
|
|
|
|
if (gFixedTimeStep>0)
|
|
{
|
|
|
|
sCurrentDemo->stepSimulation(gFixedTimeStep);
|
|
} else
|
|
{
|
|
sCurrentDemo->stepSimulation(deltaTime);//1./60.f);
|
|
}
|
|
}
|
|
|
|
if (renderGrid)
|
|
{
|
|
BT_PROFILE("Draw Grid");
|
|
//glPolygonOffset(3.0, 3);
|
|
//glEnable(GL_POLYGON_OFFSET_FILL);
|
|
s_app->drawGrid(dg);
|
|
|
|
}
|
|
if (renderVisualGeometry && ((gDebugDrawFlags&btIDebugDraw::DBG_DrawWireframe)==0))
|
|
{
|
|
if (visualWireframe)
|
|
{
|
|
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
|
}
|
|
BT_PROFILE("Render Scene");
|
|
sCurrentDemo->renderScene();
|
|
}
|
|
else
|
|
{
|
|
B3_PROFILE("physicsDebugDraw");
|
|
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
|
sCurrentDemo->physicsDebugDraw(gDebugDrawFlags);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
if (gui2 && s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera())
|
|
{
|
|
B3_PROFILE("setStatusBarMessage");
|
|
char msg[1024];
|
|
float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance();
|
|
float pitch = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPitch();
|
|
float yaw = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraYaw();
|
|
float camTarget[3];
|
|
float camPos[3];
|
|
s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPosition(camPos);
|
|
s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget);
|
|
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);
|
|
gui2->setStatusBarMessage(msg, true);
|
|
}
|
|
|
|
}
|
|
|
|
static int toggle = 1;
|
|
if (renderGui)
|
|
{
|
|
B3_PROFILE("renderGui");
|
|
#ifndef BT_NO_PROFILE
|
|
|
|
if (!pauseSimulation || singleStepSimulation)
|
|
{
|
|
if (isProfileWindowVisible(s_profWindow))
|
|
{
|
|
processProfileData(s_profWindow,false);
|
|
}
|
|
}
|
|
#endif //#ifndef BT_NO_PROFILE
|
|
|
|
|
|
if (sUseOpenGL2)
|
|
{
|
|
|
|
saveOpenGLState(s_instancingRenderer->getScreenWidth()*s_window->getRetinaScale(), s_instancingRenderer->getScreenHeight()*s_window->getRetinaScale());
|
|
}
|
|
|
|
if (m_internalData->m_gui)
|
|
{
|
|
gBlockGuiMessages = true;
|
|
m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight());
|
|
|
|
|
|
gBlockGuiMessages = false;
|
|
}
|
|
|
|
if (sUseOpenGL2)
|
|
{
|
|
restoreOpenGLState();
|
|
}
|
|
|
|
}
|
|
|
|
singleStepSimulation = false;
|
|
|
|
|
|
toggle=1-toggle;
|
|
{
|
|
BT_PROFILE("Sync Parameters");
|
|
if (s_parameterInterface)
|
|
{
|
|
s_parameterInterface->syncParameters();
|
|
}
|
|
}
|
|
{
|
|
BT_PROFILE("Swap Buffers");
|
|
s_app->swapBuffer();
|
|
}
|
|
|
|
if (gui2)
|
|
{
|
|
B3_PROFILE("forceUpdateScrollBars");
|
|
gui2->forceUpdateScrollBars();
|
|
}
|
|
|
|
}
|
|
|
|
void OpenGLExampleBrowser::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
|
|
{
|
|
gDisableDemoSelection = true;
|
|
sSharedMem = sharedMem;
|
|
}
|