I am working on a C program to be compiled to WASM and display an image in the browser. The point of this program is to learn to set things up using EGL, and therefore I am not interested in any answers involving e.g. SDL, GLFW, etc.
This code works to clear the screen to blue (I've ommitted error checking to reduce size):
#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;
}
But as soon as I add the following after glClearColor(...)
, I no longer see a blue screen in the browser:
const GLuint vertex_shader = load_shader(GL_VERTEX_SHADER, VERTEX_SHADER);
const GLuint fragment_shader = load_shader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
I suspect the shader code is not at all relevent to the problem, but just in case, here is the code for load_shader
, taken from the OpenGL ES 2 book (error checking ommitted)
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;
}
And the shaders themselves:
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"
"}
Here is how I compile:
EMSCRIPTEN_OPTS = \
-s WASM=1 \
-s FULL_ES2=1 \
-s MODULARIZE=1
${EMCC} main_web.c -o hello.js ${EMSCRIPTEN_OPTS}
glGetError()
is not returning an error code.
And here is my 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>
Why do I stop clearing the screen when I just load the shaders?
#version 100 es
. What is the version? Print the result ofglGetString(GL_VERSION)
respectivelyglGetString(GL_SHADING_LANGUAGE_VERSION)
, aftereglMakeCurrent
. – Gromwell'es': unexpected token). They do compile with
#version 100, but no change.
GL_VERSION` isOpenGL ES 2.0 (WebGL 1.0)
,GL_SHADING_LANGUAGE_VERSION
isOpenGL ES GLSL ES 1.00 (WebGL GLSL ES 1.0)
– Pergolesi