Emscripten is a compiler that translates code written in C and C++ to WebAssembly, or to a subset of JavaScript known as asm.js
).
Applications compiled with Emscripten are more performant and therefore faster than interpreted or dynamically compiled JavaScript.
Dependencies: CMake, gcc and Python.
On Unix-based systems:
git clone https://github.com/emscripten-core/emsdk ~/.emsdk
cd .emsdk
git pull
./emsdk install latest
./emsdk activate latest
echo 'source "${HOME}/.emsdk/emsdk_env.sh" 2>&-' >> ~/.bashrc
exec $SHELL
Test with the command:
em++ --version
Suppose you have this code:
main.cpp
#include <SDL2/SDL.h>
int main(int argc, char** argv) {
SDL_Window* window = NULL;
window = SDL_CreateWindow(
"SDL2 It's Work!",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
640, 480,
SDL_WINDOW_SHOWN
);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_SetRenderDrawColor(renderer, 9, 20, 33, 255);
while(true){
SDL_Event event;
while(SDL_PollEvent(&event)){
if( event.type == SDL_QUIT ){
exit(0);
}
}
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
//SDL_Quit();
return 0;
}
Save this image:
Compile and run:
Need SDL2 installed!
g++ main.cpp -lSDL2
./a.out
Modify the code above and make it look like this:
#include <SDL2/SDL.h>
#include <emscripten.h>
#include <iostream>
struct Context {
std::string title;
int width, height;
SDL_Renderer * renderer;
SDL_Event event;
SDL_Rect rect, rect2;
SDL_Texture * logo;
};
void callback(void * arg){
Context * context = static_cast<Context*>(arg);
while(SDL_PollEvent(&context->event)){
if( context->event.type == SDL_QUIT ){
exit(0);
}else if( context->event.type == SDL_MOUSEBUTTONDOWN ){
context->rect2.x -= 20;
}
}
SDL_RenderClear(context->renderer);
SDL_SetRenderDrawColor(context->renderer, 255, 255, 255, 255);
//SDL_RenderDrawRect(renderer, &rect2);
SDL_RenderFillRect(context->renderer, &context->rect2);
SDL_SetRenderDrawColor(context->renderer, 9, 20, 33, 255);
SDL_RenderCopy(context->renderer, context->logo, NULL, &context->rect);
SDL_RenderPresent(context->renderer);
}
int main(int argc, char** argv) {
Context context;
SDL_Init(SDL_INIT_EVERYTHING);
context.title = "SDL2 It's Works!";
context.width = 1280;
context.height = 720;
SDL_Window* window = SDL_CreateWindow(
context.title.c_str(),
50, 30,
context.width, context.height,
SDL_WINDOW_SHOWN
);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
context.renderer = renderer;
SDL_Surface * surface = SDL_LoadBMP("./sdl.bmp");
context.logo = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
context.rect.x = 50;
context.rect.y = 20;
context.rect.w = surface->w;
context.rect.h = surface->h;
context.rect2.x = 800;
context.rect2.y = 20;
context.rect2.w = 300;
context.rect2.h = 300;
emscripten_set_main_loop_arg(callback, &context, -1, 1);
SDL_DestroyTexture(context.logo);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Compile with the following command:
em++ main.cpp -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp"]' --preload-files sdl.bmp -o index.js
Create a new index.html
file and insert this content:
If the file already exists, remove all content from it and paste this code inside.
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<center>
<canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<script type='text/javascript'>
var Module = {
canvas: (function() { return document.getElementById('canvas'); })()
};
</script>
<script src="index.js"></script>
</center>
</body>
</html>
And now view and use in your browser!
After running this command the game will automatically open in your default browser.
emrun index.html
For more information visit the official website of Emscripten: