如果没有完整的程序,就很难看到所有错误。您需要使用正确的选项进行构建,从 JavaScript 正确调用您的 WASM 模块,并在 SDL 和 OpenGL 中正确设置所有内容。
这是一个工作示例:
// 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;
}
使用以下选项进行编译:
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
像这样从 HTML 启动:
<!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>
如果一切正常,您应该会在浏览器窗口中看到黑色背景上的红色三角形。
HTH。