2
0
Fork 0
ff/source/_posts/Emscripten-webgl-imgui-site-demo.md

5.7 KiB

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

My main.cpp looks like this;

//============================================================================
// 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, &current);
	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;
}