├── LICENSE ├── Makefile ├── README.md ├── build ├── js │ └── runner.html └── native │ └── data ├── data └── qafoo.png └── src ├── js.c ├── native.c ├── qafoo.c └── rendering.c /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Qafoo GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build/native/qafoo build/js/qafoo.js 2 | 3 | build/native/qafoo: src/qafoo.c src/native.c src/rendering.c 4 | if uname -a | grep -q "Darwin"; then \ 5 | gcc $^ -lglfw -lsdl -lsdl_image -framework OpenGl -o build/native/qafoo; \ 6 | else \ 7 | gcc $^ -lglfw -lSDL -lSDL_image -lGL -lGLU -o build/native/qafoo; \ 8 | fi 9 | 10 | build/js/qafoo.js build/js/qafoo.data: src/qafoo.c src/js.c src/rendering.c 11 | emcc $^ -I /usr/local/include -o build/js/qafoo.js -s LEGACY_GL_EMULATION=1 -O2 --preload-file data/qafoo.png 12 | 13 | .PHONY: clean 14 | clean: 15 | @-rm build/native/qafoo 2>/dev/null 16 | @-rm build/js/qafoo.js build/js/qafoo.data 2>/dev/null 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | emscripten-opengl-example 2 | ========================= 3 | 4 | A simple example of using emscripten to transpile an OpenGL rendered Cube from C to JavaScript 5 | -------------------------------------------------------------------------------- /build/js/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Qafoo Emscripten WebGL Demo 7 | 13 | 14 | 15 | 16 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /build/native/data: -------------------------------------------------------------------------------- 1 | ../../data/ -------------------------------------------------------------------------------- /data/qafoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QafooLabs/emscripten-opengl-example/48431b5b4db332bbbf5e2d923764778aba08169d/data/qafoo.png -------------------------------------------------------------------------------- /src/js.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | typedef void (*renderFunc)(); 6 | 7 | void doRenderingLoop(renderFunc doRendering) { 8 | emscripten_set_main_loop(doRendering, 0, 1); 9 | } 10 | -------------------------------------------------------------------------------- /src/native.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef void (*renderFunc)(); 5 | 6 | void doRenderingLoop(renderFunc doRendering) { 7 | /* Loop until the user closes the window */ 8 | while (glfwGetWindowParam( GLFW_OPENED )) 9 | { 10 | doRendering(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/qafoo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void initGlScene(); 5 | void renderGlScene(double delta); 6 | void doRenderingLoop(); 7 | 8 | double lastSceneRendered, currentSceneRendered; 9 | 10 | void renderFrame() { 11 | currentSceneRendered = glfwGetTime(); 12 | renderGlScene(currentSceneRendered - lastSceneRendered); 13 | lastSceneRendered = currentSceneRendered; 14 | glfwSwapBuffers(); 15 | } 16 | 17 | int main(void) 18 | { 19 | /* Initialize the library */ 20 | if (!glfwInit()) { 21 | printf("Could not initialize library\n"); 22 | return -1; 23 | } 24 | 25 | /* Create a windowed mode window and its OpenGL context */ 26 | if(glfwOpenWindow(640, 480, 0,0,0,0,16,0, GLFW_WINDOW) != GL_TRUE) 27 | { 28 | printf("Could not create OpenGL window\n"); 29 | glfwTerminate(); 30 | return -1; 31 | } 32 | 33 | initGlScene(); 34 | lastSceneRendered = glfwGetTime(); 35 | 36 | doRenderingLoop(&renderFrame); 37 | 38 | glfwTerminate(); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/rendering.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | float rotationX, rotationY, rotationZ; 9 | GLuint textures[1]; 10 | 11 | void initTextures() { 12 | SDL_Surface *image; 13 | if(!(image = IMG_Load("data/qafoo.png"))) { 14 | fprintf(stderr, "Could not load texture image: %s\n", IMG_GetError()); 15 | exit(-1); 16 | } 17 | 18 | glGenTextures(1, textures); 19 | glBindTexture(GL_TEXTURE_2D, textures[0]); 20 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 21 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 22 | 23 | printf("%ux%u (%u)\n", image->w, image->h, image->format->BytesPerPixel); 24 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); 25 | 26 | SDL_FreeSurface(image); 27 | 28 | glEnable(GL_TEXTURE_2D); 29 | } 30 | 31 | void initGlScene() { 32 | int sceneWidth, sceneHeight; 33 | 34 | initTextures(); 35 | 36 | glClearColor(.41f, 0.71f, 0.4f, 0.0f); 37 | glClearDepth(1.0); 38 | glDepthFunc(GL_LESS); 39 | glEnable(GL_DEPTH_TEST); 40 | glShadeModel(GL_SMOOTH); 41 | 42 | glMatrixMode(GL_PROJECTION); 43 | glLoadIdentity(); 44 | 45 | glfwGetWindowSize(&sceneWidth, &sceneHeight); 46 | gluPerspective(45.0f, (GLfloat)sceneWidth / (GLfloat)sceneHeight, 0.1f, 100.0f); 47 | 48 | glMatrixMode(GL_MODELVIEW); 49 | } 50 | 51 | void renderGlScene(double delta) { 52 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 53 | glLoadIdentity(); 54 | 55 | glTranslatef(0.0f,0.0f,-5.0f); 56 | 57 | glRotatef(rotationX,1.0f,0.0f,0.0f); 58 | glRotatef(rotationY,0.0f,1.0f,0.0f); 59 | glRotatef(rotationZ,0.0f,0.0f,1.0f); 60 | 61 | glBindTexture(GL_TEXTURE_2D, textures[0]); 62 | 63 | glBegin(GL_QUADS); 64 | 65 | // Front Face (note that the texture's corners have to match the quad's corners) 66 | glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad 67 | glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad 68 | glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad 69 | glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad 70 | 71 | // Back Face 72 | glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad 73 | glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad 74 | glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad 75 | glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad 76 | 77 | // Top Face 78 | glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad 79 | glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad 80 | glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad 81 | glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad 82 | 83 | // Bottom Face 84 | glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad 85 | glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad 86 | glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad 87 | glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad 88 | 89 | // Right face 90 | glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad 91 | glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad 92 | glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad 93 | glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad 94 | 95 | // Left Face 96 | glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad 97 | glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad 98 | glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad 99 | glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad 100 | 101 | glEnd(); 102 | 103 | rotationX += delta * 25.0f; 104 | rotationY += delta * 25.0f; 105 | rotationZ += delta * 25.0f; 106 | } 107 | --------------------------------------------------------------------------------