为什么我在 emscripten 使用“#version 300 es”得到 "unsupported shader version"?
Why do I get "unsupported shader version" using "#version 300 es" at emscripten?
我不知道为什么我在使用最新的 emscripten 1.39 的顶点着色器中使用 #version 300 es
时收到 "unsupported shader version" 错误消息。使用 #version 100
它工作正常。
const GLchar* vertex_shader_code[] = {
"#version 300 es\n"
"precision mediump float; \n"
"void main() { \n"
"gl_Position = vec4(0.0, 0.0, 0.0, 1.0); \n"
"} \n"
};
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
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);
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(CANVAS_WIDTH, CANVAS_HEIGHT, 0, &window, &renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, vertex_shader_code, 0);
glCompileShader(vertex_shader);
auto compile_success = 0;
auto compile_info_lenght = 0;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_success);
if(compile_success == GL_FALSE) {
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &compile_info_lenght);
std::string vertex_shader_log(compile_info_lenght, ' ');
glGetShaderInfoLog(vertex_shader, compile_info_lenght, NULL, &vertex_shader_log[0]);
int n = vertex_shader_log.length();
char char_array[n + 1];
strcpy(char_array, vertex_shader_log.c_str());
printf("%s\n", char_array);
glDeleteShader(vertex_shader);
return 0;
}
对于构建我使用 emcc -s main.cpp -o index.html --shell-file shell.html -s USE_SDL=2 -s FULL_ES3=1
留言:
Compiled SDL version: 2.0.9
Linked SDL version: 2.0.9
ERROR: unsupported shader version
我做错了什么?
遇到同样问题的,解决方法是SDL_WINDOW_OPENGL。
SDL_CreateWindowAndRenderer(CANVAS_WIDTH, CANVAS_HEIGHT, SDL_WINDOW_OPENGL, &window, &renderer);
没有你的完整程序,很难看出所有错误。您需要使用正确的选项进行构建,从 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>
如果一切正常,您应该会在浏览器中看到黑色背景上的红色三角形 window。
HTH.
我不知道为什么我在使用最新的 emscripten 1.39 的顶点着色器中使用 #version 300 es
时收到 "unsupported shader version" 错误消息。使用 #version 100
它工作正常。
const GLchar* vertex_shader_code[] = {
"#version 300 es\n"
"precision mediump float; \n"
"void main() { \n"
"gl_Position = vec4(0.0, 0.0, 0.0, 1.0); \n"
"} \n"
};
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
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);
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(CANVAS_WIDTH, CANVAS_HEIGHT, 0, &window, &renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, vertex_shader_code, 0);
glCompileShader(vertex_shader);
auto compile_success = 0;
auto compile_info_lenght = 0;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_success);
if(compile_success == GL_FALSE) {
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &compile_info_lenght);
std::string vertex_shader_log(compile_info_lenght, ' ');
glGetShaderInfoLog(vertex_shader, compile_info_lenght, NULL, &vertex_shader_log[0]);
int n = vertex_shader_log.length();
char char_array[n + 1];
strcpy(char_array, vertex_shader_log.c_str());
printf("%s\n", char_array);
glDeleteShader(vertex_shader);
return 0;
}
对于构建我使用 emcc -s main.cpp -o index.html --shell-file shell.html -s USE_SDL=2 -s FULL_ES3=1
留言:
Compiled SDL version: 2.0.9
Linked SDL version: 2.0.9
ERROR: unsupported shader version
我做错了什么?
遇到同样问题的,解决方法是SDL_WINDOW_OPENGL。
SDL_CreateWindowAndRenderer(CANVAS_WIDTH, CANVAS_HEIGHT, SDL_WINDOW_OPENGL, &window, &renderer);
没有你的完整程序,很难看出所有错误。您需要使用正确的选项进行构建,从 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>
如果一切正常,您应该会在浏览器中看到黑色背景上的红色三角形 window。
HTH.