--- title: Emscripten webgl/imgui site demo date: 2017-01-07 11:11:22 tags: - webgl - imgui --- Created and compiled some c++ code for doing a website in imgui on top of webgl; Launch: [Demo](test/ff-site.html) My main.cpp looks like this; ``` c++ //============================================================================ // Name : main.cpp // Author : Willem Cazander //============================================================================ #include "page/PageWindow.h" #include "page/PageController.h" #include "site/FFSiteBackground.h" #include "site/FFSiteDebug.h" #include "imgui_impl_sdl.h" #include "SOIL.h" #ifdef __EMSCRIPTEN__ #include "emscripten.h" #endif extern "C" { void ff_browser_add_resize_handler(void (*handlerFunc)(int newWidth, int newHeight)); void ff_browser_add_popstate_handler(void (*handlerFunc)(char* hrefHash)); void ff_browser_pushstate(const char* hrefHash); void ff_browser_openlink(const char* url); } void onWindowResize(int newWidth, int newHeight) { printf("Browser resized to %dx%d.\n", newWidth, newHeight); #ifdef __EMSCRIPTEN__ emscripten_set_canvas_size(newWidth, newHeight); // This probably needs that any extra elements are removed from the default shell.html. #endif SDL_SetWindowSize(PAGE_WINDOW.window, newWidth, newHeight); } void onWindowPopState(char* hrefHash) { printf("popstate url: %s\n", hrefHash); PAGE_WINDOW.setPageCurrent(PAGE_WINDOW.findPage(hrefHash)); #ifdef __EMSCRIPTEN__ free(newUrl); #endif } void renderLoop(void) { ImGui_ImplSdl_ProcessEvents(&PAGE_WINDOW.windowRun); ImGui_ImplSdl_NewFrame(PAGE_WINDOW.window); PAGE_WINDOW.draw(); glViewport(0, 0, (int) ImGui::GetIO().DisplaySize.x, (int) ImGui::GetIO().DisplaySize.y); glClearColor(PAGE_WINDOW.backgroundClearColor.x, PAGE_WINDOW.backgroundClearColor.y, PAGE_WINDOW.backgroundClearColor.z, PAGE_WINDOW.backgroundClearColor.w); glClear(GL_COLOR_BUFFER_BIT); ImGui::Render(); SDL_GL_SwapWindow(PAGE_WINDOW.window); } void initSiteContent() { FFSiteDebug* siteDebug = new FFSiteDebug(); PageController* page; const char * exampleCode = R"EOS( page = PAGE_WINDOW.addPage("pulsefire","PulseFire"); page->buildText("Pulsefire is software for the arduino."); page->buildText("Embedded flash support:")->setFont(SMALL); page->buildImage("data/pulsefire-flash.png")->setSize(300,300); page->buildText("Custom multi output pwm:")->setFont(SMALL); page->buildImage("data/pulsefire-pwm.png")->setSize(300,300); )EOS"; page = PAGE_WINDOW.addPage("home","Home"); PAGE_WINDOW.setPageCurrent(page); page->buildText("Welcome the forwardfire.net website."); page->buildText("Feature")->setFont(HEADER_SUB); page->buildText("Source in C++14")->setBullet()->setColor(ImVec4(1.0f,0.0f,1.0f,1.0f)); page->buildText("UI of ImGui webgl")->setBullet()->setColor(ImVec4(1.0f,1.0f,0.0f,1.0f)); page->buildText("Compiled by Emscripten")->setBullet()->setColor(ImVec4(0.0f,1.0f,1.0f,1.0f)); page->buildText("Frontend by Me")->setBullet()->setColor(ImVec4(1.0f,0.0f,0.0f,1.0f)); page->buildText("Example page code;")->setFont(SMALL); page->buildText(exampleCode)->setMultiLine(); page = PAGE_WINDOW.addPage("pulsefire","PulseFire"); page->buildText("Pulsefire is software for the arduino."); page->buildText("Embedded flash support:")->setFont(SMALL); page->buildImage("data/pulsefire-flash.png")->setSize(300,300); page->buildText("Custom multi output pwm:")->setFont(SMALL); page->buildImage("data/pulsefire-pwm.png")->setSize(300,300); page = PAGE_WINDOW.addPage("vasc","Vasc"); page->buildText("Old java5 crud lib"); page->buildImage("data/vasc-list.png")->setSize(300,300); page = PAGE_WINDOW.addPage("test3","Test Page3"); page->buildText("YOyo"); page->buildImage("data/home-tesla.png")->setSize(200,200); page->buildImage("data/home-pulsefire.png")->setSize(200,200); page->buildText("YOyo2"); page = PAGE_WINDOW.addPage("404","Page Not Found"); PAGE_WINDOW.setPageNotFound(page); page->setMenu(false); page->buildText("Page not found."); page = PAGE_WINDOW.addPage("debug","Debug"); page->buildText("Experimental debug options."); page->buildLink("http://www.x4o.org"); page->addComponent(siteDebug); PAGE_WINDOW.addLayer(siteDebug); PAGE_WINDOW.addLayer(new FFSiteBackground()); } int main(void) { printf("ff-site: boot\n"); printf("ff-site: init video\n"); if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("Error: %s\n", SDL_GetError()); return -1; } printf("ff-site: init window\n"); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_DisplayMode current; SDL_GetCurrentDisplayMode(0, ¤t); PAGE_WINDOW.window = SDL_CreateWindow("ForwardFire Site", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); PAGE_WINDOW.glcontext = SDL_GL_CreateContext(PAGE_WINDOW.window); // Setup ImGui binding printf("ff-site: init imgui\n"); ImGui_ImplSdl_Init(PAGE_WINDOW.window); printf("ff-site: init site\n"); ImGui::GetStyle().FrameRounding = 6; initSiteContent(); PAGE_WINDOW.printDebug(); PAGE_FONT.loadFonts(); printf("ff-site: started\n"); #ifdef __EMSCRIPTEN__ ff_browser_add_popstate_handler(onWindowPopState); ff_browser_add_resize_handler(onWindowResize); PAGE_WINDOW.platformOpenUrl = ff_browser_openlink; PAGE_WINDOW.platformPageCb = ff_browser_pushstate; emscripten_set_main_loop(renderLoop, 0, 0); #else while (PAGE_WINDOW.windowRun) { renderLoop(); } printf("ff-site: shutdown\n"); // Cleanup ImGui_ImplSdl_Shutdown(); SDL_GL_DeleteContext(PAGE_WINDOW.glcontext); SDL_DestroyWindow(PAGE_WINDOW.window); SDL_Quit(); #endif return EXIT_SUCCESS; } ```