我使用SDL2和GLES3编写一个简单的GUI工具包。我的司机都是新手。代码运行良好,直到我尝试编译一个着色器程序,这导致在执行glLinkProgram分割错误。GDB显示错误发生在mesa的link_interface_blocks.cpp
│ 308 validate_intrastage_interface_blocks(struct gl_shader_program *prog,│
│ 309 const gl_shader **shader_list, │
│ 310 unsigned num_shaders) │
│ 311 { │
│ 312 interface_block_definitions in_interfaces; │
│ 313 interface_block_definitions out_interfaces; │
│ 314 interface_block_definitions uniform_interfaces; │
│ 315 interface_block_definitions buffer_interfaces; │
│ 316 │
│ 317 for (unsigned int i = 0; i < num_shaders; i++) { │
│ 318 if (shader_list[i] == NULL) │
│ 319 continue; │
│ 320 │
│ > 321 foreach_in_list(ir_instruction, node, shader_list[i]->ir) { │
│ 322 ir_variable *var = node->as_variable(); │
│ 323 if (!var) │
│ 324 continue;
导致错误的最少代码:
#define GLEW_STATIC
#include "voidgui.h"
#include "table.h"
#include "window.h"
#include <GLES3/gl3.h>
#include <SDL2/SDL.h>
#include "common_frag_src.h"
#include "common_vert_src.h"
static GLuint compile_shader(GLuint type, const GLchar *src) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
GLint ok;
glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
if (ok == GL_FALSE) {
GLint log_len;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len);
char *log = calloc(log_len, sizeof(char));
glGetShaderInfoLog(shader, log_len, NULL, log);
printf("Failed to compile shadern %sn", log);
glDeleteShader(shader);
shader = 0;
}
return shader;
}
static GLuint link_program(const GLchar *vert_src, const GLchar *frag_src) {
GLuint vert = compile_shader(GL_VERTEX_SHADER, vert_src);
if (!vert) {
goto error;
}
GLuint frag = compile_shader(GL_FRAGMENT_SHADER, frag_src);
if (!frag) {
glDeleteShader(vert);
goto error;
}
GLuint prog = glCreateProgram();
glAttachShader(prog, vert);
glAttachShader(prog, frag);
glLinkProgram(prog);
glDetachShader(prog, vert);
glDetachShader(prog, frag);
glDeleteShader(vert);
glDeleteShader(frag);
GLint ok;
glGetProgramiv(prog, GL_LINK_STATUS, &ok);
if (ok == GL_FALSE) {
;
printf("Failed to link shadern");
glDeleteProgram(prog);
goto error;
}
return prog;
error:
return 0;
}
struct void_window *void_gui_init(int time) {
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Window *window =
SDL_CreateWindow("Void", 100, 100, 800, 600, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(window);
link_program(common_vert_src, common_frag_src); // arrays that contain shaders
return 0;
}
顶点着色器:
attribute vec2 pos;
void main() {
gl_Position = vec4(pos, 0.0, 1.0);
}
片段着色器:
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
着色器似乎编译正确,程序确实被创建。如果我注释掉glAttachShader
链接失败,没有分割错误。在我看来,这是一个初始化错误,尽管上面的大部分代码是从其他项目复制的。
在重新格式化着色器并将我的配置文件更正为ES后,我已经得到了它的工作。这里的教训是,你应该弄清楚你到底在用什么,以避免不必要的麻烦。