Skip to content

Commit 15c9321

Browse files
committed
WASM: Processing.cpp compiles and runs in browser via emscripten
- Guard glMaterialf/glMaterialfv with #ifndef EMSCRIPTEN - Replace glfwGetError (not in emscripten GLFW stub) - Guard settle loop and pre-loop blocking sections - Add emscripten_set_main_loop_arg for browser render loop - Add emscripten.h/html5.h includes under #ifdef EMSCRIPTEN - Verified: ellipse/background render correctly in Chrome
1 parent 61c8fae commit 15c9321

1 file changed

Lines changed: 50 additions & 1 deletion

File tree

src/Processing.cpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#endif
88

99
#include "Processing.h"
10+
#ifdef EMSCRIPTEN
11+
#include <emscripten.h>
12+
#include <emscripten/html5.h>
13+
#endif
1014
#include <csignal>
1115
#include <cstdlib>
1216
#include <cmath>
@@ -1914,7 +1918,9 @@ void PApplet::normal(float nx, float ny, float nz) { glNormal3f(nx, ny, nz); }
19141918

19151919
void PApplet::ambient(float r, float g, float b) {
19161920
GLfloat col[] = { lc(r), lc(g), lc(b), 1.0f };
1921+
#ifndef EMSCRIPTEN
19171922
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, col);
1923+
#endif
19181924
}
19191925
void PApplet::ambient(color c) {
19201926
unsigned int v = c.value;
@@ -1925,7 +1931,9 @@ void PApplet::ambient(color c) {
19251931

19261932
void PApplet::emissive(float r, float g, float b) {
19271933
GLfloat col[] = { lc(r), lc(g), lc(b), 1.0f };
1934+
#ifndef EMSCRIPTEN
19281935
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, col);
1936+
#endif
19291937
}
19301938
void PApplet::emissive(color c) {
19311939
unsigned int v = c.value;
@@ -1936,7 +1944,9 @@ void PApplet::emissive(color c) {
19361944

19371945
void PApplet::specular(float r, float g, float b) {
19381946
GLfloat col[] = { lc(r), lc(g), lc(b), 1.0f };
1947+
#ifndef EMSCRIPTEN
19391948
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col);
1949+
#endif
19401950
}
19411951
void PApplet::specular(color c) {
19421952
unsigned int v = c.value;
@@ -1946,7 +1956,9 @@ void PApplet::specular(color c) {
19461956
}
19471957

19481958
void PApplet::shininess(float s) {
1959+
#ifndef EMSCRIPTEN
19491960
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, s);
1961+
#endif
19501962
}
19511963

19521964
// =============================================================================
@@ -3054,7 +3066,7 @@ void PApplet::run(){
30543066
glfwWindowHint(GLFW_STENCIL_BITS,8); // needed for concave shape fill
30553067
gWindow=glfwCreateWindow(winWidth,winHeight,g_sketchName.c_str(),nullptr,nullptr);
30563068
if(!gWindow){
3057-
const char* err=nullptr; glfwGetError(&err);
3069+
const char* err="unknown"; (void)err;
30583070
fprintf(stderr,"[ERR] glfwCreateWindow() failed: %s\n", err?err:"unknown");
30593071
#ifdef _WIN32
30603072
MessageBoxA(NULL,
@@ -3203,12 +3215,15 @@ void PApplet::run(){
32033215
glfwSwapBuffers(gWindow);
32043216
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
32053217
glfwSwapBuffers(gWindow);
3218+
#ifndef EMSCRIPTEN
32063219
for (int _settle = 0; _settle < 5; _settle++) {
32073220
glClearColor(0.8f,0.8f,0.8f,1);
32083221
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
32093222
glfwPollEvents();
32103223
glfwSwapBuffers(gWindow);
32113224
}
3225+
}
3226+
#endif
32123227
if (!defaultP3D) setProjection(winWidth, winHeight);
32133228

32143229
this->setup();
@@ -3278,6 +3293,7 @@ void PApplet::run(){
32783293

32793294
redrawOnce = looping;
32803295
auto last=std::chrono::steady_clock::now();
3296+
#ifndef EMSCRIPTEN
32813297
// Drain Windows message queue before entering main loop.
32823298
// On Windows, a WM_QUIT from a previous sketch run can be in the queue.
32833299
// Poll multiple times to flush it, then forcibly clear the close flag.
@@ -3293,6 +3309,8 @@ void PApplet::run(){
32933309
glfwSwapBuffers(gWindow);
32943310
}
32953311
}
3312+
#endif
3313+
#ifndef EMSCRIPTEN
32963314
while(!glfwWindowShouldClose(gWindow)){
32973315

32983316
if(looping||redrawOnce){
@@ -3394,14 +3412,26 @@ void PApplet::run(){
33943412
// Reset material to neutral so non-lit objects look correct
33953413
GLfloat matWhite[] = { 0.8f, 0.8f, 0.8f, 1.0f };
33963414
GLfloat matBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3415+
#ifndef EMSCRIPTEN
33973416
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matBlack);
3417+
#endif
3418+
#ifndef EMSCRIPTEN
33983419
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matWhite);
3420+
#endif
3421+
#ifndef EMSCRIPTEN
33993422
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matBlack);
3423+
#endif
3424+
#ifndef EMSCRIPTEN
34003425
glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
3426+
#endif
34013427
// Reset specular material to none
34023428
GLfloat noSpec[] = {0,0,0,1};
3429+
#ifndef EMSCRIPTEN
34033430
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, noSpec);
3431+
#endif
3432+
#ifndef EMSCRIPTEN
34043433
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, noSpec);
3434+
#endif
34053435

34063436
// Draw guard: handle different sketch types
34073437
if (!looping && _staticSketchSetup) {
@@ -3449,6 +3479,25 @@ void PApplet::run(){
34493479
}
34503480
if(phongProg){glDeleteProgram(phongProg);phongProg=0;}
34513481
glfwDestroyWindow(gWindow);gWindow=nullptr;glfwTerminate();
3482+
#else
3483+
emscripten_set_main_loop_arg([](void* arg){
3484+
auto* p = static_cast<PApplet*>(arg);
3485+
if(p->looping||p->redrawOnce){
3486+
p->redrawOnce=false;
3487+
glViewport(0, 0, p->winWidth, p->winHeight);
3488+
glMatrixMode(GL_PROJECTION); glLoadIdentity();
3489+
glOrtho(0, p->logicalW, p->logicalH, 0, -1, 1);
3490+
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
3491+
glDisable(GL_DEPTH_TEST);
3492+
glDisable(GL_LIGHTING);
3493+
p->_backgroundCalledThisFrame=false;
3494+
++p->frameCount;
3495+
p->draw();
3496+
p->pmouseX=p->mouseX; p->pmouseY=p->mouseY;
3497+
p->mouseDX=0; p->mouseDY=0;
3498+
}
3499+
}, this, 0, 1);
3500+
#endif
34523501
}
34533502

34543503
// =============================================================================

0 commit comments

Comments
 (0)