编译着色器后程序停止绘制

Program stops drawing after compiling shaders

我正在编写一个要编译为 WASM 并在浏览器中显示图像的 C 程序。这个程序的重点是学习使用 EGL 进行设置,因此我对涉及例如的任何答案都不感兴趣。 SDL、GLFW 等

此代码用于将屏幕清除为蓝色(我省略了错误检查以减小大小):

#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "emscripten.h"

struct Environment
{
    EGLint majorVersion;
    EGLint minorVersion;

    EGLDisplay display;
    EGLSurface surface;
};

static struct Environment g_env = {};

bool initGL(struct Environment* env)
{
    env->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    eglInitialize(env->display, &env->majorVersion, &env->minorVersion);

    EGLint numConfigs = 0;
    EGLint attribList[] = 
    {
        EGL_RED_SIZE, 5,
        EGL_GREEN_SIZE, 6,
        EGL_BLUE_SIZE, 5,
        EGL_DEPTH_SIZE, 1,
        EGL_NONE
    };
    EGLConfig config;
    eglChooseConfig(env->display, attribList, &config, 1, &numConfigs);

    env->surface = eglCreateWindowSurface(env->display, config, 0, NULL);

    static const EGLint contextAttribList[] = 
    {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
    };
    EGLContext context = eglCreateContext(env->display, config, EGL_NO_CONTEXT, contextAttribList);


    eglMakeCurrent(env->display, env->surface, env->surface, context);


    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);


    return true;
}

void draw()
{
    glViewport(0, 0, 300, 150);
    glClear(GL_COLOR_BUFFER_BIT);
    eglSwapBuffers(g_env.display, g_env.surface);
}

int main(int argc, char *argv[])
{
    if (!initGL(&g_env))
    {
        return 1;
    }
    emscripten_set_main_loop(clearScreen, 0, 1);
    return 0;
}

但是在 glClearColor(...) 之后添加以下内容后,我就不再在浏览器中看到蓝屏了:

const GLuint vertex_shader = load_shader(GL_VERTEX_SHADER, VERTEX_SHADER);
const GLuint fragment_shader = load_shader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER);

我怀疑着色器代码与问题完全无关,但为了以防万一,这里是 load_shader 的代码,摘自 OpenGL ES 2 book(省略了错误检查)

GLuint load_shader ( GLenum type, const char *shaderSrc )
{
   GLuint shader;
   GLint compiled;

   // Create the shader object
   shader = glCreateShader ( type );

   // Load the shader source
   glShaderSource ( shader, 1, &shaderSrc, NULL );

   // Compile the shader
   glCompileShader ( shader );

   // Check the compile status
   glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );

   return shader;
}

以及着色器本身:

char VERTEX_SHADER[] =  
  "attribute vec4 vPosition;    \n"
  "void main()                  \n"
  "{                            \n"
  "   gl_Position = vPosition;  \n"
  "}                            \n";

char FRAGMENT_SHADER[] =  
  "precision mediump float;\n"\
  "void main()                                  \n"
  "{                                            \n"
  "  gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
  "}   

以下是我的编译方式:

EMSCRIPTEN_OPTS = \
-s WASM=1 \
-s FULL_ES2=1 \
-s MODULARIZE=1
${EMCC} main_web.c -o hello.js ${EMSCRIPTEN_OPTS}

glGetError() 未返回错误代码。

这是我的 HTML:

<html>
<body>
<p id="output" />
<canvas id="canvas"></canvas>
<script type="application/javascript" src="hello.js"></script>
<script type="application/javascript">
    Module({
        canvas: (() => document.getElementById('canvas'))(),
        print: (() => {
            var element = document.getElementById('output');
            return function(text) {
                element.innerHTML += text + "<br>";
            };
        })()
    })
</script>
</body>
</html>

为什么我刚加载着色器时就停止清屏了?

问题出在 HTML。打印到标准输出时,内联元素与块 <canvas> 元素发生冲突。

通过将 <p id="output"/> 包装在 div 中解决了问题。