bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled) { s_state.widgetId++; unsigned int id = (s_state.areaId << 16) | s_state.widgetId; int x = s_state.widgetX; int y = s_state.widgetY - BUTTON_HEIGHT; int w = s_state.widgetW; int h = BUTTON_HEIGHT; s_state.widgetY -= BUTTON_HEIGHT; // + DEFAULT_SPACING; const int cx = x + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; const int cy = y + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); if (checked) AddGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 2, SetRGBA(255, 255, 255, isActive(id) ? 255 : 200)); else AddGfxCmdTriangle(cx, cy, CHECK_SIZE, CHECK_SIZE, 1, SetRGBA(255, 255, 255, isActive(id) ? 255 : 200)); if (enabled) AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200)); else AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200)); if (subtext) AddGfxCmdText(x + w - BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, subtext, SetRGBA(255, 255, 255, 128)); return res; }
bool imguiCheck(const char* text, bool checked, bool enabled) { s_state.widgetId++; unsigned int id = (s_state.areaId << 16) | s_state.widgetId; int x = s_state.widgetX; int y = s_state.widgetY - BUTTON_HEIGHT; int w = s_state.widgetW; int h = BUTTON_HEIGHT; s_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING; bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); const int cx = x + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; const int cy = y + BUTTON_HEIGHT / 2 - CHECK_SIZE / 2; AddGfxCmdRoundedRect((float)cx - 3, (float)cy - 3, (float)CHECK_SIZE + 6, (float)CHECK_SIZE + 6, 4, SetRGBA(128, 128, 128, isActive(id) ? 196 : 96)); if (checked) { if (enabled) AddGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE / 2 - 1, SetRGBA(255, 255, 255, isActive(id) ? 255 : 200)); else AddGfxCmdRoundedRect((float)cx, (float)cy, (float)CHECK_SIZE, (float)CHECK_SIZE, (float)CHECK_SIZE / 2 - 1, SetRGBA(128, 128, 128, 200)); } if (enabled) AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200)); else AddGfxCmdText(x + BUTTON_HEIGHT, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200)); return res; }
void imguiLabel(const char* text) { int x = s_state.widgetX; int y = s_state.widgetY - BUTTON_HEIGHT; s_state.widgetY -= BUTTON_HEIGHT; AddGfxCmdText(x, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(255, 255, 255, 255)); }
bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scroll) { s_state.areaId++; s_state.widgetId = 0; g_scrollId = (s_state.areaId << 16) | s_state.widgetId; s_state.widgetX = x + SCROLL_AREA_PADDING; s_state.widgetY = y + h - AREA_HEADER + (*scroll); s_state.widgetW = w - SCROLL_AREA_PADDING * 4; g_scrollTop = y - AREA_HEADER + h; g_scrollBottom = y + SCROLL_AREA_PADDING; g_scrollRight = x + w - SCROLL_AREA_PADDING * 3; g_scrollVal = scroll; g_scrollAreaTop = s_state.widgetY; g_focusTop = y - AREA_HEADER; g_focusBottom = y - AREA_HEADER + h; g_insideScrollArea = inRect(x, y, w, h, false); s_state.insideCurrentScroll = g_insideScrollArea; AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 6, SetRGBA(0, 0, 0, 192)); AddGfxCmdText(x + AREA_HEADER / 2, y + h - AREA_HEADER / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, name, SetRGBA(255, 255, 255, 128)); AddGfxCmdScissor(x + SCROLL_AREA_PADDING, y + SCROLL_AREA_PADDING, w - SCROLL_AREA_PADDING * 4, h - AREA_HEADER - SCROLL_AREA_PADDING); return g_insideScrollArea; }
void imguiValue(const char* text) { const int x = s_state.widgetX; const int y = s_state.widgetY - BUTTON_HEIGHT; const int w = s_state.widgetW; s_state.widgetY -= BUTTON_HEIGHT; AddGfxCmdText(x + w - BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, text, SetRGBA(255, 255, 255, 200)); }
void DebugDraw::DrawString(int x, int y, const char *string, ...) { b2::float32 h = static_cast<b2::float32>(g_camera.m_height); char buffer[128]; va_list arg; va_start(arg, string); std::vsprintf(buffer, string, arg); va_end(arg); AddGfxCmdText(float(x), h - float(y), TEXT_ALIGN_LEFT, buffer, SetRGBA(230, 153, 153, 255)); }
bool imguiButton(const char* text, bool enabled) { s_state.widgetId++; unsigned int id = (s_state.areaId << 16) | s_state.widgetId; int x = s_state.widgetX; int y = s_state.widgetY - BUTTON_HEIGHT; int w = s_state.widgetW; int h = BUTTON_HEIGHT; s_state.widgetY -= BUTTON_HEIGHT + DEFAULT_SPACING; bool over = enabled && inRect(x, y, w, h); bool res = buttonLogic(id, over); AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, (float)BUTTON_HEIGHT / 2 - 1, SetRGBA(128, 128, 128, isActive(id) ? 196 : 96)); if (enabled) AddGfxCmdText(x + BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200)); else AddGfxCmdText(x + BUTTON_HEIGHT / 2, y + BUTTON_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200)); return res; }
void DebugDraw::DrawString(const b2::Vec2& pw, const char *string, ...) { b2::Vec2 ps = g_camera.ConvertWorldToScreen(pw); b2::float32 h = static_cast<b2::float32>(g_camera.m_height); char buffer[128]; va_list arg; va_start(arg, string); std::vsprintf(buffer, string, arg); va_end(arg); AddGfxCmdText(ps.x, h - ps.y, TEXT_ALIGN_LEFT, buffer, SetRGBA(230, 153, 153, 255)); }
void AddGfxCmdText(int x, int y, TextAlign align, const char* text, unsigned int color) { AddGfxCmdText(float(x), float(y), align, text, color); }
int main(int argc, char** argv) { #if defined(_WIN32) // Enable memory-leak reports _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); #endif g_camera.m_width = 1024; g_camera.m_height = 640; if (glfwInit() == 0) { fprintf(stderr, "Failed to initialize GLFW\n"); return -1; } char title[64]; sprintf(title, "Box2D Testbed Version %d.%d.%d", b2_version.major, b2_version.minor, b2_version.revision); #if defined(__APPLE__) // Not sure why, but these settings cause glewInit below to crash. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif mainWindow = glfwCreateWindow(g_camera.m_width, g_camera.m_height, title, NULL, NULL); if (mainWindow == NULL) { fprintf(stderr, "Failed to open GLFW mainWindow.\n"); glfwTerminate(); return -1; } glfwMakeContextCurrent(mainWindow); printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); glfwSetScrollCallback(mainWindow, sScrollCallback); glfwSetWindowSizeCallback(mainWindow, sResizeWindow); glfwSetKeyCallback(mainWindow, sKeyCallback); glfwSetMouseButtonCallback(mainWindow, sMouseButton); glfwSetCursorPosCallback(mainWindow, sMouseMotion); glfwSetScrollCallback(mainWindow, sScrollCallback); #if defined(__APPLE__) == FALSE //glewExperimental = GL_TRUE; GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); exit(EXIT_FAILURE); } #endif g_debugDraw.Create(); sCreateUI(); testCount = 0; while (g_testEntries[testCount].createFcn != NULL) { ++testCount; } testIndex = b2Clamp(testIndex, 0, testCount - 1); testSelection = testIndex; entry = g_testEntries + testIndex; test = entry->createFcn(); // Control the frame rate. One draw per monitor refresh. glfwSwapInterval(1); double time1 = glfwGetTime(); double frameTime = 0.0; glClearColor(0.3f, 0.3f, 0.3f, 1.f); while (!glfwWindowShouldClose(mainWindow)) { glfwGetWindowSize(mainWindow, &g_camera.m_width, &g_camera.m_height); glViewport(0, 0, g_camera.m_width, g_camera.m_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); unsigned char mousebutton = 0; int mscroll = ui.scroll; ui.scroll = 0; double xd, yd; glfwGetCursorPos(mainWindow, &xd, &yd); int mousex = int(xd); int mousey = int(yd); mousey = g_camera.m_height - mousey; int leftButton = glfwGetMouseButton(mainWindow, GLFW_MOUSE_BUTTON_LEFT); if (leftButton == GLFW_PRESS) mousebutton |= IMGUI_MBUT_LEFT; imguiBeginFrame(mousex, mousey, mousebutton, mscroll); sSimulate(); sInterface(); // Measure speed double time2 = glfwGetTime(); double alpha = 0.9f; frameTime = alpha * frameTime + (1.0 - alpha) * (time2 - time1); time1 = time2; char buffer[32]; snprintf(buffer, 32, "%.1f ms", 1000.0 * frameTime); AddGfxCmdText(5, 5, TEXT_ALIGN_LEFT, buffer, WHITE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); RenderGLFlush(g_camera.m_width, g_camera.m_height); glfwSwapBuffers(mainWindow); glfwPollEvents(); } g_debugDraw.Destroy(); RenderGLDestroy(); glfwTerminate(); return 0; }
bool imguiSlider(const char* text, int* val, int vmin, int vmax, int vinc, bool enabled) { s_state.widgetId++; unsigned int id = (s_state.areaId << 16) | s_state.widgetId; int x = s_state.widgetX; int y = s_state.widgetY - BUTTON_HEIGHT; int w = s_state.widgetW; int h = SLIDER_HEIGHT; s_state.widgetY -= SLIDER_HEIGHT + DEFAULT_SPACING; AddGfxCmdRoundedRect((float)x, (float)y, (float)w, (float)h, 4.0f, SetRGBA(0, 0, 0, 128)); const int range = w - SLIDER_MARKER_WIDTH; float u = (*val - vmin) / float(vmax - vmin); if (u < 0) u = 0; if (u > 1) u = 1; int m = (int)(u * range); bool over = enabled && inRect(x + m, y, SLIDER_MARKER_WIDTH, SLIDER_HEIGHT); bool res = buttonLogic(id, over); bool valChanged = false; if (isActive(id)) { if (s_state.wentActive) { s_state.dragX = s_state.mx; s_state.dragOrig = u; } if (s_state.dragX != s_state.mx) { u = s_state.dragOrig + (float)(s_state.mx - s_state.dragX) / (float)range; if (u < 0) u = 0; if (u > 1) u = 1; *val = int(vmin + u*(vmax - vmin)); *val = int(floorf(*val / float(vinc) + 0.5f))*vinc; // Snap to vinc m = (int)(u * range); valChanged = true; } } if (isActive(id)) AddGfxCmdRoundedRect((float)(x + m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, SetRGBA(255, 255, 255, 255)); else AddGfxCmdRoundedRect((float)(x + m), (float)y, (float)SLIDER_MARKER_WIDTH, (float)SLIDER_HEIGHT, 4.0f, isHot(id) ? SetRGBA(255, 196, 0, 128) : SetRGBA(255, 255, 255, 64)); char msg[128]; snprintf(msg, 128, "%d", *val); if (enabled) { AddGfxCmdText(x + SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200)); AddGfxCmdText(x + w - SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, msg, isHot(id) ? SetRGBA(255, 196, 0, 255) : SetRGBA(255, 255, 255, 200)); } else { AddGfxCmdText(x + SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_LEFT, text, SetRGBA(128, 128, 128, 200)); AddGfxCmdText(x + w - SLIDER_HEIGHT / 2, y + SLIDER_HEIGHT / 2 - TEXT_HEIGHT / 2, TEXT_ALIGN_RIGHT, msg, SetRGBA(128, 128, 128, 200)); } return res || valChanged; }