Without your full program, it is difficult to see everything that is wrong. You need to build with the correct options, call your WASM module correctly from JavaScript, and set up everything correctly in SDL and OpenGL.
Here is a working example:
// main.cpp
#include <stdio.h>
#include <stdarg.h>
#include <emscripten.h>
#include <SDL.h>
#include <SDL_opengles2.h>
SDL_Window *sdlWindow;
static const char *vertexShaderSource[] = {
"#version 300 es\n"
"in vec4 position;\n"
"void main(void) {\n"
" gl_Position = vec4(position.xyz, 1.0);\n"
"}\n"
};
static const char *fragmentShaderSource[] = {
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 fragColor;\n"
"void main(void) {\n"
" fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n"
};
static void
fatal(const char *const fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
printf("\n");
va_end(args);
for (;;) {
SDL_Delay(1000);
}
}
static GLuint
compileShader(GLenum shaderType, const char **shaderSource)
{
GLuint shdr = glCreateShader(shaderType);
glShaderSource(shdr, 1, shaderSource, nullptr);
glCompileShader(shdr);
GLint isCompiled = 0;
glGetShaderiv(shdr, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE) {
GLint maxLength = 0;
glGetShaderiv(shdr, GL_INFO_LOG_LENGTH, &maxLength);
char *errorString = (char *) malloc(maxLength + 1);
glGetShaderInfoLog(shdr, maxLength, &maxLength, errorString);
fatal("Compile failed: %s", errorString);
}
return shdr;
}
static void
_set_SDL_Attribute(SDL_GLattr attr, int value, const char *attrName)
#define set_SDL_Attribute(x, v) _set_SDL_Attribute(x, v, #x)
{
if (SDL_GL_SetAttribute(attr, value) != 0) {
fatal("SDL set attrib failed: %s, %s", attrName, SDL_GetError());
}
}
static void
setupSDL(void)
{
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fatal("Unable to init SDL: %s", SDL_GetError());
}
SDL_version compiled;
SDL_version linked;
SDL_VERSION(&compiled);
SDL_GetVersion(&linked);
printf("Compiled SDL version: %d.%d.%d\n",
compiled.major, compiled.minor, compiled.patch);
printf("Linked SDL version: %d.%d.%d\n",
linked.major, linked.minor, linked.patch);
set_SDL_Attribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
set_SDL_Attribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
set_SDL_Attribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
set_SDL_Attribute(SDL_GL_DOUBLEBUFFER, 1);
set_SDL_Attribute(SDL_GL_DEPTH_SIZE, 24);
SDL_Renderer *renderer;
if (SDL_CreateWindowAndRenderer(400, 400, SDL_WINDOW_OPENGL,
&sdlWindow, &renderer) < 0) {
fatal("Unable to create windown: %s", SDL_GetError());
}
SDL_GLContext glContext = SDL_GL_CreateContext(sdlWindow);
if (glContext == NULL) {
fatal("Unable to create context: %s", SDL_GetError());
}
printf("GL Version={%s}\n", glGetString(GL_VERSION));
printf("GLSL Version={%s}\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
}
static void
setupOpenGL(void)
{
GLuint shaderProgram = glCreateProgram();
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER,
fragmentShaderSource);
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
static const GLfloat vertices[] = { 0.0f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f };
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0); // Input offset is zero.
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black
}
static void
mainLoop(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
SDL_GL_SwapWindow(sdlWindow);
}
int
main(void)
{
setupSDL();
setupOpenGL();
emscripten_set_main_loop(mainLoop, 0, true);
return 0;
}
Compile with these options:
emcc main.cpp -O3 -Wall -Wextra -Werror -s WASM=1 -s USE_SDL=2 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -o foo.js
Launch from HTML like this:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>Wasm Test Page</h1>
<canvas id=canvas width=400 height=400 oncontextmenu="event.preventDefault()"></canvas>
<script>var Module = { canvas: document.getElementById('canvas') }; </script>
<script src="foo.js"></script>
</body>
</html>
If everything works, you should see a red triangle on a black background in your browser window.
HTH.