Project

General

Profile

Feature #27

Add webgl to WASM build

Added by Kevin O'Dwyer 10 months ago. Updated 3 months ago.

Status:
New
Priority:
Normal
Assignee:
Category:
Emscripten
Target version:
Start date:
05/17/2020
Due date:
% Done:

0%

Estimated time:

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

#2

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
boxedwine-shell.js:917 0009:err:d3d:wined3d_check_gl_call >>>>>>> GL_INVALID_ENUM (0x500) from extension detection
adapter_gl.c / 3691.
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")

#3

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

#4

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

#5

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

#6

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.

Also available in: Atom PDF