Emscripten 无法编译着色器

Emscripten fails to compile shader

我正在使用带有 C++ 17 和 WebGL 1.0 的 emscripten 来尝试在 OpenGL 中绘制一些基本的东西。但我似乎无法通过着色器编译。我尝试了许多不同类型的着色器来消除着色器成为问题的可能性。

我的假设是它是着色器文本的编码,但我似乎无法弄清楚。也许有人已经遇到过这个问题并可以提供解决方案。

编译:

-s ENVIRONMENT=web
-s TOTAL_MEMORY=2147483648
-s MODULARIZE=1
-s EXPORT_ES6=1
-s DEMANGLE_SUPPORT=1
-s USE_PTHREADS=0
-s GL_ASSERTIONS=1
-s GL_DEBUG=1
--preload-file ./assets@/

如果您尝试构建一个最小程序,assets 中的文件名是 standard.vertstandard.frag

着色器

顶点着色器:

precision mediump float;

attribute vec2 vertPosition;
attribute vec3 vertColor;

varying vec3 fragColor;

void main() {
    fragColor = vertColor;
    gl_Position = vec4(vertPosition, 0.0, 1.0);
}

片段着色器:

precision mediump float;

varying vec3 fragColor;

void main() {
    gl_FragColor = vec4(fragColor, 1.0);
}

加载器

readFile

std::string readFile( FILE* file )
{
    fseek( file, 0L, SEEK_END );
    long buffSize = ftell( file );
    rewind( file );

    std::string buffer( buffSize, '[=13=]' );

    fread( (void*)buffer.c_str(), 1, buffSize, file );

    return buffer;
}
GLenum ErrorCheckValue  = glGetError();
GLint  gl_shader_result = GL_FALSE;
int    InfoLogLength;

std::string vertex_src;
std::string frag_src;
FILE*       fp = nullptr;

fp = fopen( "/standard.vert", "r" );
if ( !fp )
{
    emscripten_console_error( "No file found for vertex shader" );
    return;
}

vertex_src = readFile( fp );
emscripten_console_logf( "Vertex Shader:\n%s", vertex_src.c_str() );
fclose( fp );

fp = fopen( "/standard.frag", "r" );
if ( !fp )
{
    emscripten_console_error( "No file found for fragment shader" );
    return;
}

frag_src = readFile( fp );
emscripten_console_logf( "Fragment Shader:\n%s", frag_src.c_str() );
fclose( fp );

const char* vertexCode = vertex_src.c_str();
const char* fragCode   = frag_src.c_str();

u32 vertexShaderId = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShaderId, 1, (const GLchar* const*)vertexCode, NULL );
glCompileShader( vertexShaderId );

// check for vertex shader errors
glGetShaderiv( vertexShaderId, GL_COMPILE_STATUS, &gl_shader_result );
glGetShaderiv( vertexShaderId, GL_INFO_LOG_LENGTH, &InfoLogLength );

if ( InfoLogLength > 0 )
{
    std::string msg( InfoLogLength + 1, '[=14=]' );

    glGetShaderInfoLog( vertexShaderId, InfoLogLength, NULL, (GLchar*)msg.c_str() );

    emscripten_console_error( ( "WASM:: Vertex shader error: " + msg ).c_str() );

    return;
}

u32 fragmentShaderId = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragmentShaderId, 1, (const GLchar* const*)fragCode, NULL );
glCompileShader( fragmentShaderId );

// check for vertex shader errors
glGetShaderiv( fragmentShaderId, GL_COMPILE_STATUS, &gl_shader_result );
glGetShaderiv( fragmentShaderId, GL_INFO_LOG_LENGTH, &InfoLogLength );

if ( InfoLogLength > 0 )
{
    std::string msg( InfoLogLength + 1, '[=14=]' );

    glGetShaderInfoLog( fragmentShaderId, InfoLogLength, NULL, (GLchar*)msg.c_str() );

    emscripten_console_error( ( "WASM:: Fragment shader error: " + msg ).c_str() );

    return;
}

u32 shaderProgramId = glCreateProgram();
glAttachShader( shaderProgramId, vertexShaderId );
glAttachShader( shaderProgramId, fragmentShaderId );
glLinkProgram( shaderProgramId );

// Check the program
glGetProgramiv( shaderProgramId, GL_LINK_STATUS, &gl_shader_result );
glGetProgramiv( shaderProgramId, GL_INFO_LOG_LENGTH, &InfoLogLength );
if ( InfoLogLength > 0 )
{
    std::string msg( InfoLogLength + 1, '[=14=]' );

    glGetProgramInfoLog( shaderProgramId, InfoLogLength, NULL, (GLchar*)msg.c_str() );

    emscripten_console_error( ( "WASM:: Shader compilation error: " + msg ).c_str() );

    return;
}

emscripten_console_log( "WASM:: Compiled shaders" );

glDetachShader( shaderProgramId, vertexShaderId );
glDetachShader( shaderProgramId, fragmentShaderId );

glDeleteShader( vertexShaderId );
glDeleteShader( fragmentShaderId );

当然还有错误:glCompileShader: ERROR: 1:1: '' : syntax error

感谢您耐心阅读这一切。任何评论、建议或解决方案总是更好 none 谢谢。

我不确定这是否是因为 WebGL 1.0/2.0 是 OpenGL ES2/ES3,但为了让 WebGL 正确读取着色器代码,它需要指向包含着色器代码。

要对顶点和片段着色器进行的更正是:

glShaderSource( vertexShaderId, 1, (const GLchar**)&vertexCode, NULL );

glShaderSource( fragmentShaderId, 1, (const GLchar**)&fragCode, NULL );