diff --git a/Demos3/CpuDemos/main_opengl3core.cpp b/Demos3/CpuDemos/main_opengl3core.cpp new file mode 100644 index 000000000..01a5e078d --- /dev/null +++ b/Demos3/CpuDemos/main_opengl3core.cpp @@ -0,0 +1,968 @@ + +//#include "GpuDemo.h" + +#ifdef _WIN32 +#include //for GetLocalTime/GetSystemTime +#else +#include //gettimeofday +#endif + +#ifdef __APPLE__ +#include "OpenGLWindow/MacOpenGLWindow.h" +#elif defined _WIN32 +#include "OpenGLWindow/Win32OpenGLWindow.h" +#elif defined __linux +#include "OpenGLWindow/X11OpenGLWindow.h" +#endif + + + +#include "OpenGLWindow/GLPrimitiveRenderer.h" +#include "OpenGLWindow/GLInstancingRenderer.h" + +#include +#include +#include "OpenGLTrueTypeFont/fontstash.h" +#include "OpenGLTrueTypeFont/opengl_fontstashcallbacks.h" +#include "../GpuDemos/gwenUserInterface.h" + +#include "../btgui/Timing/b3Quickprof.h" +#include "../btgui/OpenGLWindow/GLRenderToTexture.h" + +bool exportFrame=false; +bool exportMovie = false; +int frameIndex = 0; +GLRenderToTexture* renderTexture =0; + +int g_OpenGLWidth=1024; +int g_OpenGLHeight = 768; +bool dump_timings = false; +int maxFrameCount = 102; +extern char OpenSansData[]; + +static void MyResizeCallback( float width, float height) +{ + g_OpenGLWidth = width; + g_OpenGLHeight = height; +} + +b3gWindowInterface* window=0; +GwenUserInterface* gui = 0; + +bool gPause = false; +bool gDrawGui = true; +bool gStep = false; +bool gReset = false; + +enum +{ + MYPAUSE=1, + MYPROFILE=2, + MYRESET, +}; + +enum +{ + MYCOMBOBOX1 = 1, +}; + +struct CpuDemo +{ + + struct ConstructionInfo + { + bool m_useInstancedCollisionShapes; + GLInstancingRenderer* m_instancingRenderer; + GLPrimitiveRenderer* m_primRenderer; + + class b3gWindowInterface* m_window; + class GwenUserInterface* m_gui; + + ConstructionInfo() + :m_useInstancedCollisionShapes(true), + m_instancingRenderer(0), + m_window(0), + m_gui(0) + { + } + }; + + + virtual void initPhysics(const ConstructionInfo& ci)=0; + + virtual void exitPhysics()=0; + + virtual void renderScene()=0; + + virtual void clientMoveAndDisplay()=0; + + + virtual const char* getName() { + return ""; + } + virtual bool mouseMoveCallback(float x,float y) + { + return false; + } + virtual bool mouseButtonCallback(int button, int state, float x, float y) + { + return false; + } + virtual bool keyboardCallback(int key, int state) + { + return false; + } + + typedef class CpuDemo* (CreateFunc)(); +}; + +struct EmptyDemo : public CpuDemo +{ + virtual const char* getName() { + return "EmptyDemo"; + } + + virtual void initPhysics(const ConstructionInfo& ci) + { + } + + virtual void exitPhysics() + { + } + + virtual void renderScene() + { + } + + virtual void clientMoveAndDisplay() + { + } + + static CpuDemo* MyCreateFunc() + { + CpuDemo* demo = new EmptyDemo; + return demo; + } + + +}; + +b3AlignedObjectArray demoNames; +int selectedDemo = 0; +CpuDemo::CreateFunc* allDemos[]= +{ + EmptyDemo::MyCreateFunc, +}; + + +void MyComboBoxCallback(int comboId, const char* item) +{ + int numDemos = demoNames.size(); + for (int i=0;imouseMoveCallback(x,y); + if (!handled) + { + if (sDemo) + handled = sDemo->mouseMoveCallback(x,y); + if (!handled) + b3DefaultMouseMoveCallback(x,y); + } + } +} +static void MyMouseButtonCallback(int button, int state, float x, float y) +{ + if (gui) + { + bool handled = gui->mouseButtonCallback(button,state,x,y); + if (!handled) + { + //try picking first + if (sDemo) + handled = sDemo->mouseButtonCallback(button,state,x,y); + + if (!handled) + b3DefaultMouseButtonCallback(button,state,x,y); + } + } +} + +extern bool useShadowMap; + +void MyKeyboardCallback(int key, int state) +{ + if (key=='s' && state) + { + useShadowMap=!useShadowMap; + } + if (key=='g' && state) + { + gDrawGui = !gDrawGui; + } + + if (key==B3G_ESCAPE && window) + { + window->setRequestExit(); + } + if (key==B3G_F2) + { + if (state) + exportMovie = !exportMovie; + } + if (key==B3G_F1) + { + if (state) + exportFrame = true; + } + if (sDemo) + sDemo->keyboardCallback(key,state); + + b3DefaultKeyboardCallback(key,state); +} + + + + + + + int droidRegular=0;//, droidItalic, droidBold, droidJapanese, dejavu; + +sth_stash* stash=0; +OpenGL2RenderCallbacks* renderCallbacks = 0; + +void exitFont() +{ + sth_delete(stash); + stash=0; + + delete renderCallbacks; + renderCallbacks=0; +} +sth_stash* initFont(GLPrimitiveRenderer* primRender) +{ + GLint err; + + struct sth_stash* stash = 0; + int datasize; + + float sx,sy,dx,dy,lh; + GLuint texture; + + renderCallbacks = new OpenGL2RenderCallbacks(primRender); + + stash = sth_create(512,512,renderCallbacks);//256,256);//,1024);//512,512); + err = glGetError(); + assert(err==GL_NO_ERROR); + + if (!stash) + { + fprintf(stderr, "Could not create stash.\n"); + return 0; + } +#ifdef LOAD_FONT_FROM_FILE + unsigned char* data=0; + const char* fontPaths[]={ + "./", + "../../bin/", + "../bin/", + "bin/" + }; + + int numPaths=sizeof(fontPaths)/sizeof(char*); + + // Load the first truetype font from memory (just because we can). + + FILE* fp = 0; + const char* fontPath ="./"; + char fullFontFileName[1024]; + + for (int i=0;i] [--benchmark] [--maxFrameCount=][--dump_timings] [--disable_opencl] [--cl_device=] [--cl_platform=] [--disable_cached_cl_kernels] [--load_cl_kernels_from_disk] [--x_dim=] [--y_dim=] [--z_dim=] [--x_gap=] [--y_gap=] [--z_gap=] [--use_concave_mesh] [--pair_benchmark_file=] [--new_batching] [--no_instanced_collision_shapes]\n"); +}; + + +void DumpSimulationTime(FILE* f) +{ + b3ProfileIterator* profileIterator = b3ProfileManager::Get_Iterator(); + + profileIterator->First(); + if (profileIterator->Is_Done()) + return; + + float accumulated_time=0,parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + int i; + int frames_since_reset = b3ProfileManager::Get_Frame_Count_Since_Reset(); + + //fprintf(f,"%.3f,", parent_time ); + float totalTime = 0.f; + + + + static bool headersOnce = true; + + if (headersOnce) + { + headersOnce = false; + fprintf(f,"root,"); + + for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + { + float current_total_time = profileIterator->Get_Current_Total_Time(); + accumulated_time += current_total_time; + float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; + const char* name = profileIterator->Get_Current_Name(); + fprintf(f,"%s,",name); + } + fprintf(f,"\n"); + } + + + fprintf(f,"%.3f,",parent_time); + profileIterator->First(); + for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + { + float current_total_time = profileIterator->Get_Current_Total_Time(); + accumulated_time += current_total_time; + float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; + const char* name = profileIterator->Get_Current_Name(); + //if (!strcmp(name,"stepSimulation")) + { + fprintf(f,"%.3f,",current_total_time); + } + totalTime += current_total_time; + //recurse into children + } + + fprintf(f,"\n"); + + + b3ProfileManager::Release_Iterator(profileIterator); + + +} +///extern const char* g_deviceName; +const char* g_deviceName = "blaat"; + +#include "Bullet3Common/b3Vector3.h" + +FILE* defaultOutput = stdout; + +void myprintf(const char* msg) +{ + fprintf(defaultOutput,msg); +} + + + + + +//#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "OpenGLTrueTypeFont/stb_image_write.h" +void writeTextureToPng(int textureWidth, int textureHeight, const char* fileName) +{ + int numComponents = 4; + //glPixelStorei(GL_PACK_ALIGNMENT,1); + GLuint err=glGetError(); + assert(err==GL_NO_ERROR); + glReadBuffer(GL_BACK);//COLOR_ATTACHMENT0); + err=glGetError(); + assert(err==GL_NO_ERROR); + float* orgPixels = (float*)malloc(textureWidth*textureHeight*numComponents*4); + glReadPixels(0,0,textureWidth, textureHeight, GL_RGBA, GL_FLOAT, orgPixels); + //it is useful to have the actual float values for debugging purposes + + //convert float->char + char* pixels = (char*)malloc(textureWidth*textureHeight*numComponents); + err=glGetError(); + assert(err==GL_NO_ERROR); + + for (int j=0;jcreateWindow(wci); + window->setResizeCallback(MyResizeCallback); + window->setMouseMoveCallback(MyMouseMoveCallback); + window->setMouseButtonCallback(MyMouseButtonCallback); + window->setKeyboardCallback(MyKeyboardCallback); + + window->setWindowTitle("Bullet 3.x GPU Rigid Body http://bulletphysics.org"); + + + +#ifndef __APPLE__ + glewInit(); +#endif + + gui = new GwenUserInterface(); + + b3Printf("started GwenUserInterface\n"); + + + GLPrimitiveRenderer prim(g_OpenGLWidth,g_OpenGLHeight); + + stash = initFont(&prim); + + + if (gui) + { + gui->init(g_OpenGLWidth,g_OpenGLHeight,stash,window->getRetinaScale()); + + b3Printf("init fonts\n"); + + + gui->setToggleButtonCallback(MyButtonCallback); + + gui->registerToggleButton(MYPAUSE,"Pause"); + gui->registerToggleButton(MYPROFILE,"Profile"); + gui->registerToggleButton(MYRESET,"Reset"); + + int numItems = sizeof(allDemos)/sizeof(CpuDemo::CreateFunc*); + demoNames.clear(); + for (int i=0;igetName()); + delete demo; + } + + gui->registerComboBox(MYCOMBOBOX1,numItems,&demoNames[0]); + gui->setComboBoxCallback(MyComboBoxCallback); + } + + + + do + { + bool syncOnly = false; + gReset = false; + + + + + static bool once=true; + + + //glClearColor(0.3f, 0.3f, 0.3f, 1.0f); + glClearColor(1,1,1,1); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + window->setWheelCallback(b3DefaultWheelCallback); + + + + + { + CpuDemo* demo = allDemos[selectedDemo](); + sDemo = demo; +// demo->myinit(); + bool useGpu = false; + + + int maxObjectCapacity=128*1024; + //maxObjectCapacity = b3Max(maxObjectCapacity,ci.arraySizeX*ci.arraySizeX*ci.arraySizeX+10); + + + CpuDemo::ConstructionInfo ci; + ci.m_instancingRenderer = new GLInstancingRenderer(maxObjectCapacity);//render.getInstancingRenderer(); + ci.m_window = window; + ci.m_gui = gui; + ci.m_instancingRenderer->init(); + ci.m_instancingRenderer->resize(g_OpenGLWidth,g_OpenGLHeight); + ci.m_instancingRenderer->InitShaders(); + ci.m_primRenderer = &prim; + + +// render.init(); + + + { + demo->initPhysics(ci); + } + + + + + + + + FILE* csvFile = 0; + FILE* detailsFile = 0; + + if (benchmark) + { + gPause = false; + char prefixFileName[1024]; + char csvFileName[1024]; + char detailsFileName[1024]; + + + + //todo: move this time stuff into the Platform/Window class +#ifdef _WIN32 + SYSTEMTIME time; + GetLocalTime(&time); + char buf[1024]; + DWORD dwCompNameLen = 1024; + if (0 != GetComputerName(buf, &dwCompNameLen)) + { + printf("%s", buf); + } else + { + printf("unknown", buf); + } + + sprintf(prefixFileName,"%s_%s_%s_date_%d-%d-%d_time_%d-%d-%d","CPU",buf,demoNames[selectedDemo],time.wDay,time.wMonth,time.wYear,time.wHour,time.wMinute,time.wSecond); + +#else + timeval now; + gettimeofday(&now,0); + + struct tm* ptm; + ptm = localtime (&now.tv_sec); + char buf[1024]; +#ifdef __APPLE__ + sprintf(buf,"MacOSX"); +#else + sprintf(buf,"Unix"); +#endif + sprintf(prefixFileName,"%s_%s_%s_%d_%d_%d_date_%d-%d-%d_time_%d-%d-%d",info.m_deviceName,buf,demoNames[selectedDemo],ci.arraySizeX,ci.arraySizeY,ci.arraySizeZ, + ptm->tm_mday, + ptm->tm_mon+1, + ptm->tm_year+1900, + ptm->tm_hour, + ptm->tm_min, + ptm->tm_sec); + +#endif + + sprintf(csvFileName,"%s.csv",prefixFileName); + sprintf(detailsFileName,"%s.txt",prefixFileName); + printf("Open csv file %s and details file %s\n", csvFileName,detailsFileName); + + //GetSystemTime(&time2); + + csvFile=fopen(csvFileName,"w"); + detailsFile = fopen(detailsFileName,"w"); + if (detailsFile) + defaultOutput = detailsFile; + + //if (f) + // fprintf(f,"%s (%dx%dx%d=%d),\n", g_deviceName,ci.arraySizeX,ci.arraySizeY,ci.arraySizeZ,ci.arraySizeX*ci.arraySizeY*ci.arraySizeZ); + } + + + + + do + { + + + GLint err = glGetError(); + assert(err==GL_NO_ERROR); + + + if (exportFrame || exportMovie) + { + + if (!renderTexture) + { + renderTexture = new GLRenderToTexture(); + GLuint renderTextureId; + glGenTextures(1, &renderTextureId); + + // "Bind" the newly created texture : all future texture functions will modify this texture + glBindTexture(GL_TEXTURE_2D, renderTextureId); + + // Give an empty image to OpenGL ( the last "0" ) + //glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, g_OpenGLWidth,g_OpenGLHeight, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0); + //glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA32F, g_OpenGLWidth,g_OpenGLHeight, 0,GL_RGBA, GL_FLOAT, 0); + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA32F, g_OpenGLWidth,g_OpenGLHeight, 0,GL_RGBA, GL_FLOAT, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + renderTexture->init(g_OpenGLWidth,g_OpenGLHeight,renderTextureId, RENDERTEXTURE_COLOR); + } + + bool result = renderTexture->enable(); + } + + err = glGetError(); + assert(err==GL_NO_ERROR); + + b3ProfileManager::Reset(); + b3ProfileManager::Increment_Frame_Counter(); + +// render.reshape(g_OpenGLWidth,g_OpenGLHeight); + ci.m_instancingRenderer->resize(g_OpenGLWidth,g_OpenGLHeight); + prim.setScreenSize(g_OpenGLWidth,g_OpenGLHeight); + + err = glGetError(); + assert(err==GL_NO_ERROR); + + window->startRendering(); + + err = glGetError(); + assert(err==GL_NO_ERROR); + + glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);//|GL_STENCIL_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + + err = glGetError(); + assert(err==GL_NO_ERROR); + + if (!gPause) + { + B3_PROFILE("clientMoveAndDisplay"); + + demo->clientMoveAndDisplay(); + } + else + { + + } + + { + B3_PROFILE("renderScene"); + demo->renderScene(); + } + err = glGetError(); + assert(err==GL_NO_ERROR); + + + /*if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getNumCollisionObjects()) + { + B3_PROFILE("renderPhysicsWorld"); + b3AlignedObjectArray arr = demo->getDynamicsWorld()->getCollisionObjectArray(); + b3CollisionObject** colObjArray = &arr[0]; + + render.renderPhysicsWorld(demo->getDynamicsWorld()->getNumCollisionObjects(),colObjArray, syncOnly); + syncOnly = true; + + } + */ + + + if (exportFrame || exportMovie) + { + + char fileName[1024]; + sprintf(fileName,"screenShot%d.png",frameIndex++); + writeTextureToPng(g_OpenGLWidth,g_OpenGLHeight,fileName); + exportFrame = false; + renderTexture->disable(); + } + + + { + B3_PROFILE("gui->draw"); + if (gui && gDrawGui) + gui->draw(g_OpenGLWidth,g_OpenGLHeight); + } + err = glGetError(); + assert(err==GL_NO_ERROR); + + + { + B3_PROFILE("window->endRendering"); + window->endRendering(); + } + + err = glGetError(); + assert(err==GL_NO_ERROR); + + { + B3_PROFILE("glFinish"); + } + + + + if (dump_timings) + { + b3ProfileManager::dumpAll(stdout); + } + + if (csvFile) + { + static int frameCount=0; + + if (frameCount>0) + { + DumpSimulationTime(csvFile); + if (detailsFile) + { + fprintf(detailsFile,"\n==================================\nFrame %d:\n", frameCount); + b3ProfileManager::dumpAll(detailsFile); + } + } + + if (frameCount>=maxFrameCount) + window->setRequestExit(); + frameCount++; + } + + + if (gStep) + gPause=true; + + } while (!window->requestedExit() && !gReset); + + + demo->exitPhysics(); + b3ProfileManager::CleanupMemory(); + delete ci.m_instancingRenderer; + + delete demo; + sDemo = 0; + + if (detailsFile) + { + fclose(detailsFile); + detailsFile=0; + } + if (csvFile) + { + fclose(csvFile); + csvFile=0; + } + } + + + + } while (gReset); + + + if (gui) + gui->setComboBoxCallback(0); + + { + + + + delete gui; + gui=0; + + exitFont(); + + + window->closeWindow(); + delete window; + window = 0; + + } + + return 0; +} diff --git a/Demos3/CpuDemos/premake4.lua b/Demos3/CpuDemos/premake4.lua new file mode 100644 index 000000000..1345f64a1 --- /dev/null +++ b/Demos3/CpuDemos/premake4.lua @@ -0,0 +1,81 @@ + + +project ("App_Bullet3_CPU_Demos") + +language "C++" + +kind "ConsoleApp" +targetdir "../../bin" + + +initOpenGL() +initGlew() + +includedirs { + "..", + "../../src", + "../../btgui" +} + +links { + "gwen", + "Bullet2FileLoader", + "Bullet3Dynamics", + "Bullet3Collision", + "Bullet3Geometry", + "Bullet3Common", +} + +files { + "**.cpp", + "**.h", + + "../Wavefront/tiny_obj_loader.cpp", + "../Wavefront/tiny_obj_loader.h", + + "../../btgui/OpenGLWindow/GLInstancingRenderer.cpp", + "../../btgui/OpenGLWindow/GLInstancingRenderer.h", + "../../btgui/OpenGLWindow/GLPrimitiveRenderer.cpp", + "../../btgui/OpenGLWindow/GLPrimitiveRenderer.h", + "../../btgui/OpenGLWindow/LoadShader.cpp", + "../../btgui/OpenGLWindow/LoadShader.h", + "../../btgui/OpenGLWindow/TwFonts.cpp", + "../../btgui/OpenGLWindow/TwFonts.h", + "../../btgui/OpenGLWindow/GLRenderToTexture.cpp", + "../../btgui/OpenGLWindow/GLRenderToTexture.h", + "../../btgui/OpenGLTrueTypeFont/fontstash.cpp", + "../../btgui/OpenGLTrueTypeFont/fontstash.h", + "../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.cpp", + "../../btgui/OpenGLTrueTypeFont/opengl_fontstashcallbacks.h", + "../../btgui/FontFiles/OpenSans.cpp", + "../../btgui/stb_image/stb_image.cpp", + "../../btgui/stb_image/stb_image.h", + "../../btgui/Timing/b3Quickprof.cpp", + "../../btgui/Timing/b3Quickprof.h", + "../../btgui/Timing/b3Clock.cpp", + "../../btgui/Timing/b3Clock.h", +} + +if os.is("Windows") then + files{ + "../../btgui/OpenGLWindow/Win32OpenGLWindow.cpp", + "../../btgui/OpenGLWindow/Win32OpenGLWindow.h", + "../../btgui/OpenGLWindow/Win32Window.cpp", + "../../btgui/OpenGLWindow/Win32Window.h", + } +end +if os.is("Linux") then + links{"X11"} + files { + "../../btgui/OpenGLWindow/X11OpenGLWindow.cpp", + "../../btgui/OpenGLWindow/X11OpenGLWindows.h" + } +end +if os.is("MacOSX") then + links {"Cocoa.framework"} + files { + "../../btgui/OpenGLWindow/MacOpenGLWindow.h", + "../../btgui/OpenGLWindow/MacOpenGLWindow.mm", + } +end +