├── 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 |
--------------------------------------------------------------------------------