@ -14,24 +14,16 @@
# include <SDL.h>
# include <SDL_opengles2.h>
// Emscripten requires to have full control over the main loop. We're going to store variables from main() to main_loop() here.
// This will also hold some of our persistent data across loops. Remember: imgui is immediate mode, and doesn't store state.
// Emscripten requires to have full control over the main loop. We're going to store our SDL book-keeping variables globally.
// Having a single function that acts as a loop prevents us to store state in the stack of said function. So we need some location for this.
struct MainLoopVars {
SDL_Window * window = NULL ;
SDL_GLContext gl_context = NULL ;
bool show_demo_window = true ;
bool show_another_window = false ;
ImVec4 clear_color = ImVec4 ( 0.45f , 0.55f , 0.60f , 1.00f ) ;
} ;
SDL_Window * g_Window = NULL ;
SDL_GLContext g_GLContext = NULL ;
// For clarity, our main loop code is declared at the end.
void main_loop ( void * ) ;
int main ( int , char * * )
{
MainLoopVars vars ;
// Setup SDL
if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_TIMER ) ! = 0 )
{
@ -39,13 +31,14 @@ int main(int, char**)
return - 1 ;
}
// For the browser using emscripten, we are going to use WebGL2 with GLES3. See the Makefile.emscripten for requirement details.
// For the browser using Emscripten, we are going to use WebGL1 with GL ES2. See the Makefile. for requirement details.
// It is very likely the generated file won't work in many browsers. Firefox is the only sure bet, but I have successfully
// run this code on Chrome for Android for example.
const char * glsl_version = " #version 300 es " ;
const char * glsl_version = " #version 100 " ;
//const char* glsl_version = "#version 300 es";
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_FLAGS , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_ES ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 3 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 2 ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , 0 ) ;
// Create window with graphics context
@ -55,9 +48,10 @@ int main(int, char**)
SDL_DisplayMode current ;
SDL_GetCurrentDisplayMode ( 0 , & current ) ;
SDL_WindowFlags window_flags = ( SDL_WindowFlags ) ( SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI ) ;
vars . window = SDL_CreateWindow ( " Dear ImGui SDL2+OpenGL3 example " , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED , 1280 , 720 , window_flags ) ;
vars . gl_context = SDL_GL_CreateContext ( vars . window ) ;
if ( ! vars . gl_context ) {
g_Window = SDL_CreateWindow ( " Dear ImGui Emscripten example " , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED , 1280 , 720 , window_flags ) ;
g_GLContext = SDL_GL_CreateContext ( g_Window ) ;
if ( ! g_GLContext )
{
fprintf ( stderr , " Failed to initialize WebGL context! \n " ) ;
return 1 ;
}
@ -74,7 +68,7 @@ int main(int, char**)
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer bindings
ImGui_ImplSDL2_InitForOpenGL ( vars. window , vars . gl_c ontext) ;
ImGui_ImplSDL2_InitForOpenGL ( g_Window, g_GLC ontext) ;
ImGui_ImplOpenGL3_Init ( glsl_version ) ;
// Load Fonts
@ -93,12 +87,18 @@ int main(int, char**)
//IM_ASSERT(font != NULL);
// This function call won't return, and will engage in an infinite loop, processing events from the browser, and dispatching them.
emscripten_set_main_loop_arg ( main_loop , & vars , 0 , true ) ;
emscripten_set_main_loop_arg ( main_loop , NULL , 0 , true ) ;
}
void main_loop( void * arg ) {
MainLoopVars * vars = ( MainLoopVars * ) arg ;
void main_loop( void * arg )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
IM_UNUSED ( arg ) ; // We can pass this argument as the second parameter of emscripten_set_main_loop_arg(), but we don't use that.
// Our state (make them static = more or less global) as a convenience to keep the example terse.
static bool show_demo_window = true ;
static bool show_another_window = false ;
static ImVec4 clear_color = ImVec4 ( 0.45f , 0.55f , 0.60f , 1.00f ) ;
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
@ -114,12 +114,12 @@ void main_loop(void* arg) {
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame ( ) ;
ImGui_ImplSDL2_NewFrame ( vars- > w indow) ;
ImGui_ImplSDL2_NewFrame ( g_W indow) ;
ImGui : : NewFrame ( ) ;
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if ( vars- > show_demo_window)
ImGui : : ShowDemoWindow ( & vars- > show_demo_window) ;
if ( show_demo_window)
ImGui : : ShowDemoWindow ( & show_demo_window) ;
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
{
@ -129,11 +129,11 @@ void main_loop(void* arg) {
ImGui : : Begin ( " Hello, world! " ) ; // Create a window called "Hello, world!" and append into it.
ImGui : : Text ( " This is some useful text. " ) ; // Display some text (you can use a format strings too)
ImGui : : Checkbox ( " Demo Window " , & vars- > show_demo_window) ; // Edit bools storing our window open/close state
ImGui : : Checkbox ( " Another Window " , & vars- > show_another_window) ;
ImGui : : Checkbox ( " Demo Window " , & show_demo_window) ; // Edit bools storing our window open/close state
ImGui : : Checkbox ( " Another Window " , & show_another_window) ;
ImGui : : SliderFloat ( " float " , & f , 0.0f , 1.0f ) ; // Edit 1 float using a slider from 0.0f to 1.0f
ImGui : : ColorEdit3 ( " clear color " , ( float * ) & vars- > clear_color) ; // Edit 3 floats representing a color
ImGui : : ColorEdit3 ( " clear color " , ( float * ) & clear_color) ; // Edit 3 floats representing a color
if ( ImGui : : Button ( " Button " ) ) // Buttons return true when clicked (most widgets return true when edited/activated)
counter + + ;
@ -145,21 +145,21 @@ void main_loop(void* arg) {
}
// 3. Show another simple window.
if ( vars- > show_another_window)
if ( show_another_window)
{
ImGui : : Begin ( " Another Window " , & vars- > show_another_window) ; // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui : : Begin ( " Another Window " , & show_another_window) ; // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui : : Text ( " Hello from another window! " ) ;
if ( ImGui : : Button ( " Close Me " ) )
vars- > show_another_window = false ;
show_another_window = false ;
ImGui : : End ( ) ;
}
// Rendering
ImGui : : Render ( ) ;
SDL_GL_MakeCurrent ( vars- > window , vars - > gl_c ontext) ;
SDL_GL_MakeCurrent ( g_Window, g_GLC ontext) ;
glViewport ( 0 , 0 , ( int ) io . DisplaySize . x , ( int ) io . DisplaySize . y ) ;
glClearColor ( vars- > clear_color. x , vars - > clear_color . y , vars- > clear_color. z , vars - > clear_color . w ) ;
glClearColor ( clear_color. x , clear_color . y , clear_color. z , clear_color . w ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
ImGui_ImplOpenGL3_RenderDrawData ( ImGui : : GetDrawData ( ) ) ;
SDL_GL_SwapWindow ( vars- > w indow) ;
SDL_GL_SwapWindow ( g_W indow) ;
}