Using emscripten with opengl shaders
I'm having trouble getting the emscripten to work with openGL shaders. The project compiles just fine with emscripten and gcc, but doesn't work when I try to run the emscripten output.
Errors I get from compiling the vertex shader:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'layout' : syntax error
Errors I get from compiling the fragment shader:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'in' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:3: '' : No precision specified for (float)
ERROR: 0:5: 'out' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:5: '' : No precision specified for (float)
I am compiling this project using the command:
em++ src/*.cpp -Iinclude/ -o test.html -std=c++11 -s USE_GLFW=3 -s FULL_ES3=1
Vertex shader source:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 in_color;
uniform mat4 model;
uniform mat4 projection;
out vec3 out_color;
void main()
{
gl_Position = projection * model * vec4(position, 1.0f);
out_color = in_color;
}
Fragment shader source:
#version 330 core
in vec3 out_color;
out vec4 color;
void main()
{
color = vec4(out_color, 1.0);
}
Shaders are loaded as char arrays from the output provided xxd -i
I am working in C ++ 11 on linux. The program works fine when I run it natively and I tried to run the emscripten output in both Firefox and Chrome.
Seems to be a problem between different versions. Is there a way to make emscripten work with what I have now, or do I need to write my shaders differently? And if I have to rewrite my shaders, how do I write them?
source to share
The shader code must be WebGL shader code to work in a browser. I don't think emscripten converts the shader code (GLSL 3.3 in this case) to GLSL ES 1.0, which is webGL compatible.
You will need to use attribute
instead in
in the vertex shader, varying
for out / in in the vertex / fragment shaders, and use gl_FragColor
as the output variable of the fragment shader. layout
is also not supported, and variables require precise definition. Check out the WebGL cheat page here .
source to share
In current emscripten, you can use WebGL2 and GLSL ES 3.00. You need to change the lines #version
to
#version 300 es
You also need to add the default precision to your fragment shaders.
If it were me, I would just bind my code to glShaderSource
, to be something like
GLint shaderSourceWrapper(GLint shader, const std::string src) {
#ifdef __EMSCRIPTEN__
// replace '#version.*' with '#version 300 es'
// if it a fragment shader add 'precision highp float'
// do anything else relevant like warn if there are
// unsupported #extension directives
#endif
glShaderSource(shader, ... )
Or even do it in JavaScript level like this
source to share