Emscripten OpenGL (3) 给出版本错误
Emscripten OpenGL (3) gives versions errors
OS X - Chrome.
我是 OpenGL / emscripten 的新手,正在尝试设置一个使用 WebGL 2、OpenGL 3+ 并通过 emscripten 构建到 webassembly 的简单脚本。
WebGL 1/OpenGL 2 的编译没有问题。并且将 canvas 设置为 WebGL 2 / OpenGL 3 似乎也有效。当我检查当前版本 运行 时,它会通知我有关 OpenGL 3.0 和 WebGL2 的信息(但也许它没有使用它..?)。
但是,emcc 仍然尖叫有关着色器的错误,im 给出的着色器仅与 3.0+ 版本兼容,因此暗示 im 运行 openGL 1/2 ?
通过 emscripten 设置新上下文
EmscriptenWebGLContextAttributes ctxAttrs;
emscripten_webgl_init_context_attributes(&ctxAttrs);
ctxAttrs.alpha = GL_TRUE;
ctxAttrs.depth = GL_TRUE;
ctxAttrs.stencil = GL_TRUE;
ctxAttrs.antialias = 4;
ctxAttrs.premultipliedAlpha = false;
ctxAttrs.preserveDrawingBuffer = false;
ctxAttrs.minorVersion = 0;
ctxAttrs.majorVersion = 2; // WebGL2
this->context = emscripten_webgl_create_context(0, &ctxAttrs);
assert(this->context > 0); // Must have received a valid context.
int res = emscripten_webgl_make_context_current(this->context);
assert(res == EMSCRIPTEN_RESULT_SUCCESS);
assert(emscripten_webgl_get_current_context() == this->context);
着色器:
const char *vertexShaderSource = "#version 300 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}[=11=]";
const char *fragmentShaderSource = "#version 300 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n[=11=]";
当我在创建上下文后立即记录当前 OpenGL 版本时,
printf("OpenGL version supported by this platform : %s\n", glGetString(GL_VERSION));
我明白了:
OpenGL version supported by this platformOpenGL ES 3.0 (WebGL 2.0
(OpenGL ES 3.0 Chromium))
Chrome 控制台这样说
ERROR::SHADER::VERTEX::COMPILATION_FAILEDERROR: 0:1: 'core' : invalid version directive
00:53:19.828 index.js:1 ERROR: 0:2: 'layout' : syntax error
00:53:19.829 index.js:1
00:53:19.830 index.js:1 ERROR::SHADER::FRAGMENT::COMPILATION_FAILEDERROR: 0:1: 'core' : invalid version directive
00:53:19.831 index.js:1 ERROR: 0:2: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
00:53:19.832 index.js:1 ERROR: 0:2: '' : No precision specified for (float)
00:53:19.833 index.js:1 ERROR: 0:5: '1.0f' : Floating-point suffix unsupported prior to GLSL ES 3.00
00:53:19.834 index.js:1 ERROR: 0:5: '1.0f' : syntax error
00:53:19.835
我这样调用 emscripten,启用 FULL_ES3 和 WEBGL2。
emcc src/main.cpp src/lib/Chart.cpp -s SAFE_HEAP=1 --bind -s WASM=1 -O3 -o index.js -s LEGACY_GL_EMULATION=0 -s GL_UNSAFE_OPTS=0 --pre-js pre-module.js --post-js post-module.js -s GL_ASSERTIONS=1 -s INVOKE_RUN=0 -std=c++11 -s USE_WEBGL2=1 -s FULL_ES3=1 -s USE_GLFW=3 -s OFFSCREENCANVAS_SUPPORT=1
谢谢!
#version 300 core
适用于 OpenGL 3。 WebGL 不支持此功能。
#version 300 es
适用于 OpenGL ES 3。这就是您想要的。
我只是想添加我的解决方案是修改 emscripten 库
将emscripten/src/library_gl.js
复制到您的项目中
编辑您的副本并将这些行添加到 getSource
的末尾
getSource: function(shader, count, string, length) {
...
const isFragmentShader = GLctx.getShaderParameter(GL.shaders[shader], 0x8B4F /* GL_SHADER_TYPE */) === 0x8B30 /* GL_FRAGMENT_SHADER */;
const header = isFragmentShader ? "#version 300 es\nprecision mediump float;\n" : "#version 300 es\n";
source = source.replace(/#version.*?\n/, header);
return source;
},
用类似
的东西编译我的代码
emcc -std=c++11 -s WASM=1 -s USE_WEBGL2=1 --js-library library_gl.js myprogram.cpp
基本上搜索并替换部分GLSL为GLSL ES。这样我就不必修改着色器,具体取决于着色器。
此外,如果您的 C++ 未打印出着色器编译和 link 错误,您可以像这样从 JavaScript 添加它们。
在你包含你的 emscripten 代码之前包含这个脚本
WebGL2RenderingContext.prototype.compileShader = (function(origFn) {
return function(shader) {
origFn.call(this, shader);
const status = this.getShaderParameter(shader, this.COMPILE_STATUS);
if (!status) {
console.error(this.getShaderInfoLog(shader));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
WebGL2RenderingContext.prototype.linkProgram = (function(origFn) {
return function(program) {
origFn.call(this, program);
const status = this.getProgramParameter(program, this.LINK_STATUS);
if (!status) {
console.error(this.getProgramInfoLog(program));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
这会将编译错误打印到 JavaScript 控制台并显示错误
示例:
WebGL2RenderingContext.prototype.compileShader = (function(origFn) {
return function(shader) {
origFn.call(this, shader);
const status = this.getShaderParameter(shader, this.COMPILE_STATUS);
if (!status) {
console.error(this.getShaderInfoLog(shader));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
WebGL2RenderingContext.prototype.linkProgram = (function(origFn) {
return function(program) {
origFn.call(this, program);
const status = this.getProgramParameter(program, this.LINK_STATUS);
if (!status) {
console.error(this.getProgramInfoLog(program));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
function main() {
const gl = document.createElement("canvas").getContext("webgl2");
if (!gl) {
alert("need webgl2");
return;
}
const vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, `#version 300 core
void main() {
gl_Position = vec4(0);
}
`);
gl.compileShader(vs);
}
main();
当我运行上面的代码时,我得到
ERROR: 0:1: 'core' : invalid version directive
OS X - Chrome.
我是 OpenGL / emscripten 的新手,正在尝试设置一个使用 WebGL 2、OpenGL 3+ 并通过 emscripten 构建到 webassembly 的简单脚本。
WebGL 1/OpenGL 2 的编译没有问题。并且将 canvas 设置为 WebGL 2 / OpenGL 3 似乎也有效。当我检查当前版本 运行 时,它会通知我有关 OpenGL 3.0 和 WebGL2 的信息(但也许它没有使用它..?)。
但是,emcc 仍然尖叫有关着色器的错误,im 给出的着色器仅与 3.0+ 版本兼容,因此暗示 im 运行 openGL 1/2 ?
通过 emscripten 设置新上下文
EmscriptenWebGLContextAttributes ctxAttrs;
emscripten_webgl_init_context_attributes(&ctxAttrs);
ctxAttrs.alpha = GL_TRUE;
ctxAttrs.depth = GL_TRUE;
ctxAttrs.stencil = GL_TRUE;
ctxAttrs.antialias = 4;
ctxAttrs.premultipliedAlpha = false;
ctxAttrs.preserveDrawingBuffer = false;
ctxAttrs.minorVersion = 0;
ctxAttrs.majorVersion = 2; // WebGL2
this->context = emscripten_webgl_create_context(0, &ctxAttrs);
assert(this->context > 0); // Must have received a valid context.
int res = emscripten_webgl_make_context_current(this->context);
assert(res == EMSCRIPTEN_RESULT_SUCCESS);
assert(emscripten_webgl_get_current_context() == this->context);
着色器:
const char *vertexShaderSource = "#version 300 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}[=11=]";
const char *fragmentShaderSource = "#version 300 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n[=11=]";
当我在创建上下文后立即记录当前 OpenGL 版本时,
printf("OpenGL version supported by this platform : %s\n", glGetString(GL_VERSION));
我明白了:
OpenGL version supported by this platformOpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium))
Chrome 控制台这样说
ERROR::SHADER::VERTEX::COMPILATION_FAILEDERROR: 0:1: 'core' : invalid version directive
00:53:19.828 index.js:1 ERROR: 0:2: 'layout' : syntax error
00:53:19.829 index.js:1
00:53:19.830 index.js:1 ERROR::SHADER::FRAGMENT::COMPILATION_FAILEDERROR: 0:1: 'core' : invalid version directive
00:53:19.831 index.js:1 ERROR: 0:2: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
00:53:19.832 index.js:1 ERROR: 0:2: '' : No precision specified for (float)
00:53:19.833 index.js:1 ERROR: 0:5: '1.0f' : Floating-point suffix unsupported prior to GLSL ES 3.00
00:53:19.834 index.js:1 ERROR: 0:5: '1.0f' : syntax error
00:53:19.835
我这样调用 emscripten,启用 FULL_ES3 和 WEBGL2。
emcc src/main.cpp src/lib/Chart.cpp -s SAFE_HEAP=1 --bind -s WASM=1 -O3 -o index.js -s LEGACY_GL_EMULATION=0 -s GL_UNSAFE_OPTS=0 --pre-js pre-module.js --post-js post-module.js -s GL_ASSERTIONS=1 -s INVOKE_RUN=0 -std=c++11 -s USE_WEBGL2=1 -s FULL_ES3=1 -s USE_GLFW=3 -s OFFSCREENCANVAS_SUPPORT=1
谢谢!
WebGL 不支持此功能。#version 300 core
适用于 OpenGL 3。
#version 300 es
适用于 OpenGL ES 3。这就是您想要的。
我只是想添加我的解决方案是修改 emscripten 库
将
emscripten/src/library_gl.js
复制到您的项目中编辑您的副本并将这些行添加到
的末尾getSource
getSource: function(shader, count, string, length) { ... const isFragmentShader = GLctx.getShaderParameter(GL.shaders[shader], 0x8B4F /* GL_SHADER_TYPE */) === 0x8B30 /* GL_FRAGMENT_SHADER */; const header = isFragmentShader ? "#version 300 es\nprecision mediump float;\n" : "#version 300 es\n"; source = source.replace(/#version.*?\n/, header); return source; },
用类似
的东西编译我的代码emcc -std=c++11 -s WASM=1 -s USE_WEBGL2=1 --js-library library_gl.js myprogram.cpp
基本上搜索并替换部分GLSL为GLSL ES。这样我就不必修改着色器,具体取决于着色器。
此外,如果您的 C++ 未打印出着色器编译和 link 错误,您可以像这样从 JavaScript 添加它们。
在你包含你的 emscripten 代码之前包含这个脚本
WebGL2RenderingContext.prototype.compileShader = (function(origFn) {
return function(shader) {
origFn.call(this, shader);
const status = this.getShaderParameter(shader, this.COMPILE_STATUS);
if (!status) {
console.error(this.getShaderInfoLog(shader));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
WebGL2RenderingContext.prototype.linkProgram = (function(origFn) {
return function(program) {
origFn.call(this, program);
const status = this.getProgramParameter(program, this.LINK_STATUS);
if (!status) {
console.error(this.getProgramInfoLog(program));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
这会将编译错误打印到 JavaScript 控制台并显示错误
示例:
WebGL2RenderingContext.prototype.compileShader = (function(origFn) {
return function(shader) {
origFn.call(this, shader);
const status = this.getShaderParameter(shader, this.COMPILE_STATUS);
if (!status) {
console.error(this.getShaderInfoLog(shader));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
WebGL2RenderingContext.prototype.linkProgram = (function(origFn) {
return function(program) {
origFn.call(this, program);
const status = this.getProgramParameter(program, this.LINK_STATUS);
if (!status) {
console.error(this.getProgramInfoLog(program));
}
};
}(WebGL2RenderingContext.prototype.compileShader));
function main() {
const gl = document.createElement("canvas").getContext("webgl2");
if (!gl) {
alert("need webgl2");
return;
}
const vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, `#version 300 core
void main() {
gl_Position = vec4(0);
}
`);
gl.compileShader(vs);
}
main();
当我运行上面的代码时,我得到
ERROR: 0:1: 'core' : invalid version directive