What runs in the browser
GL Lab compiles C11 and C++17 with Clang 8 into WebAssembly on your device. A WebGL renderer implements the fixed-function commands listed here. This is a coursework compatibility layer with selected GLU, GLUT and GLFW APIs. It does not provide a complete desktop OpenGL driver.
| Area | Implemented behavior | Limits |
|---|---|---|
| Drawing | glBegin/glEnd, vertex/color/normal scalar and vector calls; points, lines, triangles, strips, fans, quads and polygons; indexed arrays with glVertexPointer, glColorPointer, glNormalPointer, glDrawArrays, glDrawElements. | Client memory only. No VBOs, VAOs or texture coordinate arrays. Polygons must be convex. Integer colors and normals are normalized. |
| Transforms | Modelview and projection stacks, float/double matrices, translate/rotate/scale, orthographic/frustum/perspective projection, gluLookAt, viewport and matrix queries. | No texture matrix stack. Matrix stacks are limited to 64 entries. |
| Render state | Depth test, blending, face culling, scissor, point size, wide lines, line stipple, flat/smooth shading and polygon fill/line/point modes. | Polygon mode applies to both faces. Browser antialiasing is enabled at canvas creation. Point/line/polygon smoothing capabilities are rejected. Point sizes below one pixel are clamped. |
| Lighting | Eight lights, ambient/diffuse/specular/emission materials, shininess, color material, normalized transformed normals, positional/directional lights, attenuation and spotlights. | Lighting is computed at vertices on the CPU. One material applies to both faces; two-sided lighting is rejected. |
| Display lists | glGenLists, glNewList, glEndList, glCallList, glDeleteLists, glIsList. Scalar drawing/state commands, vertex/color/normal vectors, matrices and client-array draws copy their data when compiled. | Nested calls are limited to 64. Pointer-based light/material calls inside lists are rejected; set that state outside the list. No glCallLists or list-base mechanism. |
| GLU geometry | Quadric creation/deletion, spheres, cylinders, disks and partial disks. Fill/line/point styles, smooth/flat/no normals and inside/outside orientation. | Slices are 3โ200; stacks/loops 1โ200. Silhouettes and textured quadrics are rejected. Cylinders are uncapped as in GLU. No tessellator, NURBS or mipmap builders. |
| GLUT | One canvas window; display/reshape/keyboard/special-key/mouse/motion callbacks; timers, idle callbacks, menus, modifiers, redisplay, swap/flush, basic window queries. Solid/wire spheres, cubes, cones, toruses and Utah teapots. | Desktop placement is ignored with a diagnostic. Browser presentation replaces front/back window buffers. No multiple windows, overlays, game mode, color-index, accumulation, stencil, luminance or stereo buffers. |
| Bitmap text | glRasterPos, glWindowPos2, glutBitmapCharacter, glutBitmapString, width/height/length queries and seven font constants. Raster positions use the active matrices and clip volume; characters advance in pixels. | Glyphs use browser monospace, serif and sans-serif fonts. Appearance and proportional metrics approximate GLUT fonts. Pixel coverage is thresholded. No stroke fonts. |
| GLFW | Single-window creation/context selection, framebuffers/window size, title, user pointer, time, close flag, key/character/mouse/cursor/resize callbacks, input polling, buffer flush and a browser callback loop. | The loop must yield through emscripten_set_main_loop or emscripten_set_main_loop_arg. This header provides only these callback helpers and cancellation. It is not the Emscripten toolchain. Modern/core context hints, monitors, shared contexts and swap intervals other than one are rejected. |
Headers accept common GL/glut.h, GL/freeglut.h, GL/gl.h, GL/glu.h, lowercase aliases, GLUT/glut.h, GLFW/glfw3.h, and emscripten.h. windows.h is include-only compatibility; Windows APIs are unavailable. An unsupported function, state or flag produces a compiler or runtime diagnostic. Declaring a function yourself does not add an implementation.
Use a callback for each GLFW frame
A desktop while (!glfwWindowShouldClose(window)) loop prevents this synchronous WebAssembly build from handling browser messages. It fails with a diagnostic. Move the loop body into a callback and pass simulateInfiniteLoop=1, so C/C++ state stays alive while the browser schedules frames. The supported FPS values are zero or 60, both using the browser frame scheduler.
#include <GLFW/glfw3.h>
#include <emscripten.h>
GLFWwindow *window;
void frame(void) {
glfwPollEvents();
if (glfwWindowShouldClose(window)) {
emscripten_cancel_main_loop();
glfwDestroyWindow(window);
glfwTerminate();
return;
}
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(0.2f, 0.8f, 1.0f);
glVertex2f(-0.6f, -0.5f);
glVertex2f( 0.6f, -0.5f);
glVertex2f( 0.0f, 0.6f);
glEnd();
glfwSwapBuffers(window);
}
int main(void) {
if (!glfwInit()) return 1;
window = glfwCreateWindow(640, 480, "GLFW", 0, 0);
glfwMakeContextCurrent(window);
emscripten_set_main_loop(frame, 0, 1);
return 0;
}
When a program needs desktop features
GL Lab already uses your device: compilation and WebAssembly execute on your CPU, and WebGL uses the graphics capabilities exposed by your browser, normally through your GPU. Your source code stays on your device. More CPU or GPU power does not remove the browser's API restrictions.
A separately installed local helper could compile and run native programs with your computer's OpenGL driver, then present their output alongside a browser editor. That approach needs an installation and permission to execute local code; it is not included in this website. It would avoid renting a GPU server, with support depending on each student's operating system and graphics driver.
Desktop GLSL, textures, framebuffer objects, compute shaders, geometry shaders, driver extensions, OS integration and the full GLUT/GLFW libraries require a native environment or a separate implementation. Browser-only GL Lab currently does not implement them.
A GPU server can run the native program and stream its desktop to a browser, using a system such as Selkies. This route requires a GPU host, native compiler and libraries, networking and a managed remote session. It cannot be supplied by a static website alone. Another route is to port selected applications to Emscripten/WebGL and adapt their event loops; legacy OpenGL emulation still has documented limits.