Feature #27
Add webgl to WASM build
0%
Description
GL4ES is a OpenGL 2.1/1.5 to GL ES 2.0/1.1 translation library
https://github.com/ptitSeb/gl4es
An example of its use is: https://github.com/ptitSeb/stuntcarremake
Unfortunately while building the project using the latest emscripten build (May 2020) was successful, when running it fails in the browser.
History
Updated by Kevin O'Dwyer 10 months ago
2 other projects using gl4es
https://github.com/CecilHarvey/CloudCompare-web
https://github.com/parasti/neverball
Updated by Kevin O'Dwyer 10 months ago
gl4es bug fixed in commit: https://github.com/ptitSeb/gl4es/commit/e53acfadba316b080b4a99c186f4b297674fde67
stuntcarremake works again.
I'm currently seeing the following output when using with boxedwine:
boxedwine-shell.js:917 0009:err:d3d:wined3d_parse_gl_version Invalid OpenGL major version 0.
boxedwine-shell.js:917 0009:err:d3d:wined3d_parse_gl_version Invalid OpenGL version string "OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium))".
3boxedwine.js:1 WebGL: INVALID_ENUM: getParameter: invalid parameter name
emscriptenWebGLGet boxedwine.js:1
adapter_gl.c / 3691.
boxedwine-shell.js:917 0009:err:d3d:wined3d_check_gl_call >>>>>>> GL_INVALID_ENUM (0x500) from extension detection
boxedwine-shell.js:917 0009:fixme:d3d:wined3d_guess_gl_vendor Received unrecognized GL_VENDOR "WebKit". Returning GL_VENDOR_UNKNOWN.
boxedwine-shell.js:917 0009:fixme:d3d:wined3d_guess_card_vendor Received unrecognized GL_VENDOR "WebKit". Returning HW_VENDOR_NVIDIA.
boxedwine-shell.js:917 0009:fixme:d3d:select_card_handler Couldn't find a suitable card selector for GL vendor 0000 (using GL_RENDERER "WebKit WebGL")
Updated by Kevin O'Dwyer 9 months ago
updated branch emscripten/integrate-gl4es.
Now wglxgears works.
Requires changing output file boxedwine.js to force function glGetString to return major/minor version of 2.1
Updated by Kevin O'Dwyer 8 months ago
Branch emscripten/integrate-gl4es updated with latest gl4es. No change to js file required. Still testing compatability. Some sample OpenGL programs from opengl.org run when combined with GLUT, GLU and OPENGL DLL files. Testing on-going
Updated by Kevin O'Dwyer 7 months ago
Summary of changes made while investigating
Performed testing using examples from:
https://www.opengl.org/archives/resources/code/samples/glut_examples/progs.html
Using open dll files:
opengl32.dll from GLOverride. (Rename to OpenGL.dll) from http://www.vogonsdrivers.com/wrappers/files/OpenGL/OpenGL/GLOverride
And also glu, glut dlls files from: https://sourceforge.net/projects/opengl-dev/files/OpenGL%20-%20dev%20files%20-%20Windows/
With this I am successfully able to run many of the examples programs. yipee!
But none that make use of textures :(
Issues:
when compiling I see the following:
warning: undefined symbol: glCallList (referenced by top-level compiled C/C++ code)
For reference glCallList is called from the OpenGL example program: shadowfun.exe
I don't understand why. The definition in boxedwine and gl4es look the same.
Texture handling.
The smallest OpenGL example that includes textures: rasonly.exe
Attempts to get this to work were made by manually editing boxedwine.js
function: emscriptenWebGLGet
Normally a number of calls would be passed through to the hardware which doesn't work for webgl.
I used values from: https://feedback.wildfiregames.com/report/opengl
With these changes i was able to run: https://github.com/gkv311/wglinfo/releases
Replace lines around:
var result = GLctx.getParameter(name_);
with:
if (ret === undefined) {
var result = null;
if (name_ == 34811) { //0x87FB GL_VBO_FREE_MEMORY_ATI
result = new Int32Array(4);
result0 = 524288;
result1 = 0;
result2 = 0;
result3 = 0;
} else if (name_ == 36935) {//0x9047 GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
result = new Int32Array(1);
result0 = 524288;
} else if (name_ == 32883) {//0x8073 GL_MAX_3D_TEXTURE_SIZE
result = 2048;
} else if (name_ == 35658) {//0x8B4A GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB
result = 16384;
} else if (name_ == 35657) {//0x8B49 GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
result = 2048; //16384;
} else if (name_ == 35659) {//0x8B4B GL_MAX_VARYING_FLOATS_ARB or GL_MAX_VARYING_VECTORS ?
result = 16;
} else if (name_ == 36183) {//0x8D57 GL_MAX_SAMPLES
result = 8;
} else {
try {
result = GLctx.getParameter(name_);
} catch (ex) {
console.log("kev!! ex=" + ex);
}
}
To handle waiting for texture to load issue as discussed here:
https://stackoverflow.com/questions/19722247/webgl-wait-for-texture-to-load/19748905#19748905
Modify existing function to override values
function _emscripten_glTexParameteri(x0, x1, x2) {
if(x0 3553 && x1 10242) {
GLctx["texParameteri"](3553, 10242, 33071);//gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
} else if(x0 3553 && x1 10243) {
GLctx["texParameteri"](3553, 10243, 33071);//gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
} else if(x0 3553 && x1 10241) {
let tex = GLctx["createTexture"]()
GLctx["bindTexture"](3553, tex)
GLctx["texImage2D"](3553, 0, 6408 ,1 ,1 ,0, 6408, 5121, new Uint8Array([255, 0, 0, 255]));
GLctx["texParameteri"](3553, 10241, 9729);//gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
} else {
GLctx["texParameteri"](x0, x1, x2)
}
}
Made a similar change to the following 2 methods
function _emscripten_glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels) {
let tex = GLctx["createTexture"]()
GLctx["bindTexture"](3553, tex)
GLctx.texImage2D(target, level, internalFormat, width, height, border, format, type, pixels ? emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, internalFormat) : null)
}
function _emscripten_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) {
let tex = GLctx["createTexture"]()
GLctx["bindTexture"](3553, tex)
let pixs = new Uint8Array(4 * width * height);
GLctx["texImage2D"](3553, 0, 6408 ,width ,height ,0, 6408, 5121, pixs);
var pixelData = null;
if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0);
GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData)
}
Unresolved texture issue. Error in console when running Quake2:
WebGL: INVALID_ENUM: getQuery: invalid target/pname combination
function _emscripten_glGetQueryivEXT(target, pname, params) {
if (!params) {
GL.recordError(1281);
return
}
HEAP32[params >> 2] = GLctx.disjointTimerQueryExt["getQueryEXT"](target, pname)
}
For reference - params added to buildjs.sh
-s DISABLE_EXCEPTION_CATCHING=0 -s SUPPORT_LONGJMP=1 -DBOXEDWINE_HAS_SETJMP
Updated by Kevin O'Dwyer 3 months ago
Using a more recent build of gl4es and emscripten I have managed to get a simple example with textures to run.
Link here:
https://kevodwyer.github.io/boxedwine-examples/v1/boxedwine.html?app=dinoshade&p=dinoshade.exe
Code in:
https://github.com/kevodwyer/boxedwine-examples/tree/master/v1
Emscripten methods manually changed:
emscriptenWebGLGet
_emscripten_glTexImage2D
_emscripten_glTexSubImage2D
The current blocker is the need to use power-of-2 textures in WEBGL.
For example the emscripten method:
function _emscripten_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) {
var pixelData = null;
if (pixels) pixelData = emscriptenWebGLGetTexPixelData(type, format, width, height, pixels, 0);
GLctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixelData)
}
I don't know if there is a work-around.