main_imgui.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. #define USE_OPENGL2
  2. #ifdef USE_OPENGL2
  3. #include "OpenGLWindow/SimpleOpenGL2App.h"
  4. typedef SimpleOpenGL2App SimpleOpenGLApp;
  5. #else
  6. #include "OpenGLWindow/SimpleOpenGL3App.h"
  7. typedef SimpleOpenGL3App SimpleOpenGLApp;
  8. #endif //USE_OPENGL2
  9. #include "Bullet3Common/b3Quaternion.h"
  10. #include "Bullet3Common/b3CommandLineArgs.h"
  11. #include "assert.h"
  12. #include <stdio.h>
  13. char* gVideoFileName = 0;
  14. char* gPngFileName = 0;
  15. static b3WheelCallback sOldWheelCB = 0;
  16. static b3ResizeCallback sOldResizeCB = 0;
  17. static b3MouseMoveCallback sOldMouseMoveCB = 0;
  18. static b3MouseButtonCallback sOldMouseButtonCB = 0;
  19. static b3KeyboardCallback sOldKeyboardCB = 0;
  20. //static b3RenderCallback sOldRenderCB = 0;
  21. float gWidth = 1024;
  22. float gHeight = 768;
  23. SimpleOpenGLApp* app = 0;
  24. float gMouseX = 0;
  25. float gMouseY = 0;
  26. float g_MouseWheel = 0.0f;
  27. int g_MousePressed[3] = {0};
  28. int g_MousePressed2[3] = {0};
  29. #define B3_USE_IMGUI
  30. #ifdef B3_USE_IMGUI
  31. #include "OpenGLWindow/OpenGLInclude.h"
  32. #include "ThirdPartyLibs/imgui/imgui.h"
  33. static GLuint g_FontTexture = 0;
  34. void ImGui_ImplBullet_CreateDeviceObjects()
  35. {
  36. {
  37. GLint err = glGetError();
  38. assert(err == GL_NO_ERROR);
  39. }
  40. ImGuiIO& io = ImGui::GetIO();
  41. unsigned char* pixels;
  42. int width, height;
  43. io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
  44. // Upload texture to graphics system
  45. GLint last_texture;
  46. glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
  47. glGenTextures(1, &g_FontTexture);
  48. {
  49. GLint err = glGetError();
  50. assert(err == GL_NO_ERROR);
  51. }
  52. glBindTexture(GL_TEXTURE_2D, g_FontTexture);
  53. {
  54. GLint err = glGetError();
  55. assert(err == GL_NO_ERROR);
  56. }
  57. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  58. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  59. {
  60. GLint err = glGetError();
  61. assert(err == GL_NO_ERROR);
  62. }
  63. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
  64. // Store our identifier
  65. io.Fonts->TexID = (void*)(intptr_t)g_FontTexture;
  66. // Restore state
  67. glBindTexture(GL_TEXTURE_2D, last_texture);
  68. {
  69. GLint err = glGetError();
  70. assert(err == GL_NO_ERROR);
  71. }
  72. }
  73. void ImGui_ImplBullet_RenderDrawLists(ImDrawData* draw_data)
  74. {
  75. {
  76. GLint err = glGetError();
  77. assert(err == GL_NO_ERROR);
  78. }
  79. glEnable(GL_COLOR_MATERIAL);
  80. // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
  81. ImGuiIO& io = ImGui::GetIO();
  82. int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
  83. int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
  84. if (fb_width == 0 || fb_height == 0)
  85. return;
  86. draw_data->ScaleClipRects(io.DisplayFramebufferScale);
  87. // We are using the OpenGL fixed pipeline to make the example code simpler to read!
  88. // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
  89. GLint last_texture;
  90. glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
  91. GLint last_viewport[4];
  92. glGetIntegerv(GL_VIEWPORT, last_viewport);
  93. GLint last_scissor_box[4];
  94. glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
  95. glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
  96. glEnable(GL_BLEND);
  97. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  98. glDisable(GL_CULL_FACE);
  99. glDisable(GL_DEPTH_TEST);
  100. glEnable(GL_SCISSOR_TEST);
  101. glEnableClientState(GL_VERTEX_ARRAY);
  102. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  103. glEnableClientState(GL_COLOR_ARRAY);
  104. glEnable(GL_TEXTURE_2D);
  105. glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context
  106. {
  107. GLint err = glGetError();
  108. assert(err == GL_NO_ERROR);
  109. }
  110. // Setup viewport, orthographic projection matrix
  111. glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
  112. glMatrixMode(GL_PROJECTION);
  113. glPushMatrix();
  114. glLoadIdentity();
  115. glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f);
  116. glMatrixMode(GL_MODELVIEW);
  117. glPushMatrix();
  118. glLoadIdentity();
  119. {
  120. GLint err = glGetError();
  121. assert(err == GL_NO_ERROR);
  122. }
  123. // Render command lists
  124. #define OFFSETOF(TYPE, ELEMENT) ((size_t) & (((TYPE*)0)->ELEMENT))
  125. for (int n = 0; n < draw_data->CmdListsCount; n++)
  126. {
  127. const ImDrawList* cmd_list = draw_data->CmdLists[n];
  128. const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
  129. const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
  130. glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, pos)));
  131. glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, uv)));
  132. glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + OFFSETOF(ImDrawVert, col)));
  133. for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
  134. {
  135. const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
  136. if (pcmd->UserCallback)
  137. {
  138. pcmd->UserCallback(cmd_list, pcmd);
  139. }
  140. else
  141. {
  142. glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
  143. glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
  144. glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
  145. }
  146. idx_buffer += pcmd->ElemCount;
  147. }
  148. }
  149. #undef OFFSETOF
  150. // Restore modified state
  151. glDisableClientState(GL_COLOR_ARRAY);
  152. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  153. glDisableClientState(GL_VERTEX_ARRAY);
  154. glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
  155. glMatrixMode(GL_MODELVIEW);
  156. glPopMatrix();
  157. glMatrixMode(GL_PROJECTION);
  158. glPopMatrix();
  159. glPopAttrib();
  160. glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
  161. glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
  162. }
  163. #endif //B3_USE_IMGUI
  164. void MyWheelCallback(float deltax, float deltay)
  165. {
  166. g_MouseWheel += deltax + deltay;
  167. if (sOldWheelCB)
  168. sOldWheelCB(deltax, deltay);
  169. }
  170. void MyResizeCallback(float width, float height)
  171. {
  172. gWidth = width;
  173. gHeight = height;
  174. if (sOldResizeCB)
  175. sOldResizeCB(width, height);
  176. }
  177. void MyMouseMoveCallback(float x, float y)
  178. {
  179. printf("Mouse Move: %f, %f\n", x, y);
  180. gMouseX = x;
  181. gMouseY = y;
  182. if (sOldMouseMoveCB)
  183. sOldMouseMoveCB(x, y);
  184. }
  185. void MyMouseButtonCallback(int button, int state, float x, float y)
  186. {
  187. gMouseX = x;
  188. gMouseY = y;
  189. {
  190. if (button >= 0 && button < 3)
  191. {
  192. if (state)
  193. {
  194. g_MousePressed[button] = state;
  195. }
  196. g_MousePressed2[button] = state;
  197. }
  198. }
  199. if (sOldMouseButtonCB)
  200. sOldMouseButtonCB(button, state, x, y);
  201. }
  202. void MyKeyboardCallback(int keycode, int state)
  203. {
  204. //keycodes are in examples/CommonInterfaces/CommonWindowInterface.h
  205. //for example B3G_ESCAPE for escape key
  206. //state == 1 for pressed, state == 0 for released.
  207. // use app->m_window->isModifiedPressed(...) to check for shift, escape and alt keys
  208. printf("MyKeyboardCallback received key:%c in state %d\n", keycode, state);
  209. if (sOldKeyboardCB)
  210. sOldKeyboardCB(keycode, state);
  211. }
  212. bool ImGui_ImplGlfw_Init()
  213. {
  214. #if 0
  215. ImGuiIO& io = ImGui::GetIO();
  216. io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
  217. io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
  218. io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
  219. io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
  220. io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
  221. io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP;
  222. io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN;
  223. io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
  224. io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
  225. io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
  226. io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
  227. io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
  228. io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
  229. io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
  230. io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
  231. io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
  232. io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
  233. io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
  234. io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
  235. io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
  236. io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
  237. io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
  238. io.ClipboardUserData = g_Window;
  239. #ifdef _WIN32
  240. io.ImeWindowHandle = glfwGetWin32Window(g_Window);
  241. #endif
  242. #endif
  243. return true;
  244. }
  245. int main(int argc, char* argv[])
  246. {
  247. {
  248. b3CommandLineArgs myArgs(argc, argv);
  249. app = new SimpleOpenGLApp("SimpleOpenGLApp", gWidth, gHeight);
  250. {
  251. GLint err = glGetError();
  252. assert(err == GL_NO_ERROR);
  253. }
  254. ImGui::CreateContext();
  255. {
  256. GLint err = glGetError();
  257. assert(err == GL_NO_ERROR);
  258. }
  259. app->m_renderer->getActiveCamera()->setCameraDistance(13);
  260. app->m_renderer->getActiveCamera()->setCameraPitch(0);
  261. app->m_renderer->getActiveCamera()->setCameraTargetPosition(0, 0, 0);
  262. {
  263. GLint err = glGetError();
  264. assert(err == GL_NO_ERROR);
  265. }
  266. sOldKeyboardCB = app->m_window->getKeyboardCallback();
  267. app->m_window->setKeyboardCallback(MyKeyboardCallback);
  268. sOldMouseMoveCB = app->m_window->getMouseMoveCallback();
  269. app->m_window->setMouseMoveCallback(MyMouseMoveCallback);
  270. sOldMouseButtonCB = app->m_window->getMouseButtonCallback();
  271. app->m_window->setMouseButtonCallback(MyMouseButtonCallback);
  272. sOldWheelCB = app->m_window->getWheelCallback();
  273. app->m_window->setWheelCallback(MyWheelCallback);
  274. sOldResizeCB = app->m_window->getResizeCallback();
  275. app->m_window->setResizeCallback(MyResizeCallback);
  276. myArgs.GetCmdLineArgument("mp4_file", gVideoFileName);
  277. if (gVideoFileName)
  278. app->dumpFramesToVideo(gVideoFileName);
  279. myArgs.GetCmdLineArgument("png_file", gPngFileName);
  280. char fileName[1024];
  281. int textureWidth = 128;
  282. int textureHeight = 128;
  283. unsigned char* image = new unsigned char[textureWidth * textureHeight * 4];
  284. int textureHandle = app->m_renderer->registerTexture(image, textureWidth, textureHeight);
  285. int cubeIndex = app->registerCubeShape(1, 1, 1);
  286. b3Vector3 pos = b3MakeVector3(0, 0, 0);
  287. b3Quaternion orn(0, 0, 0, 1);
  288. b3Vector3 color = b3MakeVector3(1, 0, 0);
  289. b3Vector3 scaling = b3MakeVector3(1, 1, 1);
  290. {
  291. GLint err = glGetError();
  292. assert(err == GL_NO_ERROR);
  293. }
  294. app->m_renderer->registerGraphicsInstance(cubeIndex, pos, orn, color, scaling);
  295. app->m_renderer->writeTransforms();
  296. {
  297. bool dark = false;
  298. ImGuiStyle& style = ImGui::GetStyle();
  299. if (dark)
  300. {
  301. ImGui::StyleColorsDark(&style);
  302. }
  303. else
  304. {
  305. ImGui::StyleColorsLight(&style);
  306. }
  307. }
  308. {
  309. GLint err = glGetError();
  310. assert(err == GL_NO_ERROR);
  311. }
  312. do
  313. {
  314. static int frameCount = 0;
  315. frameCount++;
  316. if (gPngFileName)
  317. {
  318. printf("gPngFileName=%s\n", gPngFileName);
  319. sprintf(fileName, "%s%d.png", gPngFileName, frameCount++);
  320. app->dumpNextFrameToPng(fileName);
  321. }
  322. {
  323. GLint err = glGetError();
  324. assert(err == GL_NO_ERROR);
  325. }
  326. //update the texels of the texture using a simple pattern, animated using frame index
  327. for (int y = 0; y < textureHeight; ++y)
  328. {
  329. const int t = (y + frameCount) >> 4;
  330. unsigned char* pi = image + y * textureWidth * 3;
  331. for (int x = 0; x < textureWidth; ++x)
  332. {
  333. const int s = x >> 4;
  334. const unsigned char b = 180;
  335. unsigned char c = b + ((s + (t & 1)) & 1) * (255 - b);
  336. pi[0] = pi[1] = pi[2] = pi[3] = c;
  337. pi += 3;
  338. }
  339. }
  340. {
  341. GLint err = glGetError();
  342. assert(err == GL_NO_ERROR);
  343. }
  344. app->m_renderer->activateTexture(textureHandle);
  345. app->m_renderer->updateTexture(textureHandle, image);
  346. {
  347. GLint err = glGetError();
  348. assert(err == GL_NO_ERROR);
  349. }
  350. //float color[4] = { 255, 1, 1, 1 };
  351. //app->m_primRenderer->drawTexturedRect(100, 200, gWidth / 2 - 50, gHeight / 2 - 50, color, 0, 0, 1, 1, true);
  352. app->m_renderer->init();
  353. app->m_renderer->updateCamera(1);
  354. {
  355. GLint err = glGetError();
  356. assert(err == GL_NO_ERROR);
  357. }
  358. app->m_renderer->renderScene();
  359. {
  360. GLint err = glGetError();
  361. assert(err == GL_NO_ERROR);
  362. }
  363. //app->drawGrid();
  364. {
  365. GLint err = glGetError();
  366. assert(err == GL_NO_ERROR);
  367. }
  368. char bla[1024];
  369. sprintf(bla, "Simple test frame %d", frameCount);
  370. //app->drawText(bla, 10, 10);
  371. #ifdef B3_USE_IMGUI
  372. {
  373. bool show_test_window = true;
  374. bool show_another_window = false;
  375. ImVec4 clear_color = ImColor(114, 144, 154);
  376. // Start the frame
  377. ImGuiIO& io = ImGui::GetIO();
  378. if (!g_FontTexture)
  379. ImGui_ImplBullet_CreateDeviceObjects();
  380. io.DisplaySize = ImVec2((float)gWidth, (float)gHeight);
  381. io.DisplayFramebufferScale = ImVec2(gWidth > 0 ? ((float)1.) : 0, gHeight > 0 ? ((float)1.) : 0);
  382. io.DeltaTime = (float)(1.0f / 60.0f);
  383. io.MousePos = ImVec2((float)gMouseX, (float)gMouseY);
  384. io.RenderDrawListsFn = ImGui_ImplBullet_RenderDrawLists;
  385. for (int i = 0; i < 3; i++)
  386. {
  387. io.MouseDown[i] = g_MousePressed[i] | g_MousePressed2[i];
  388. g_MousePressed[i] = false;
  389. }
  390. io.MouseWheel = g_MouseWheel;
  391. ImGui::NewFrame();
  392. {
  393. GLint err = glGetError();
  394. assert(err == GL_NO_ERROR);
  395. }
  396. {
  397. {static float f = 0.0f;
  398. static int counter = 0;
  399. ImGui::Text("Hello, world!"); // Display some text (you can use a format string too)
  400. ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
  401. ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
  402. //ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our windows open/close state
  403. ImGui::Checkbox("Another Window", &show_another_window);
  404. if (ImGui::Button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated)
  405. counter++;
  406. ImGui::SameLine();
  407. ImGui::Text("counter = %d", counter);
  408. ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
  409. }
  410. }
  411. //ImGui::ShowTestWindow();
  412. //ImGui::ShowMetricsWindow();
  413. {
  414. GLint err = glGetError();
  415. assert(err == GL_NO_ERROR);
  416. }
  417. #if 0
  418. static float f = 0.0f;
  419. ImGui::Text("Hello, world!");
  420. ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
  421. ImGui::ColorEdit3("clear color", (float*)&clear_color);
  422. if (ImGui::Button("Test Window")) show_test_window ^= 1;
  423. if (ImGui::Button("Another Window")) show_another_window ^= 1;
  424. ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
  425. #endif
  426. ImGui::Render();
  427. }
  428. #endif //B3_USE_IMGUI
  429. {
  430. GLint err = glGetError();
  431. assert(err == GL_NO_ERROR);
  432. }
  433. app->swapBuffer();
  434. }
  435. while (!app->m_window->requestedExit())
  436. ;
  437. ImGui::DestroyContext();
  438. delete app;
  439. delete[] image;
  440. }
  441. return 0;
  442. }