为什么我的 GLSL 着色器编译失败且没有错误消息?
Why does my GLSL shader fail compilation with no error message?
我正在使用 OpenGL 和 C++ 构建游戏。我正在使用 GLFW 和 GLAD。我目前正在设置简单的着色器,但编译问题完全阻碍了我。简而言之,着色器编译失败,没有错误消息。
这是我的顶点着色器(用于绘制 2D 图像和文本):
#version 330 core
layout (location = 0) in vec2 vPosition;
layout (location = 1) in vec2 vTexCoords;
layout (location = 2) in vec4 vColor;
out vec4 fColor;
out vec2 fTexCoords;
uniform mat4 mvp;
void main()
{
vec4 position = mvp * vec4(vPosition, 0, 1);
position.y *= -1;
gl_Position = position;
fColor = vColor;
fTexCoords = vTexCoords;
}
下面是创建着色器、加载着色器源代码、编译着色器和检查错误的相关代码。
GLuint shaderId = glCreateShader(GL_VERTEX_SHADER);
std::string source = FileUtilities::ReadAllText(Paths::Shaders + filename);
GLchar const* file = source.c_str();
GLint length = static_cast<GLint>(source.size());
glShaderSource(shaderId, 0, &file, &length);
glCompileShader(shaderId);
GLint status;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
GLint logSize = 0;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logSize);
std::vector<GLchar> message = std::vector<GLchar>(logSize);
glGetShaderInfoLog(shaderId, logSize, nullptr, &message[0]);
glDeleteShader(shaderId);
std::cout << std::string(message.begin(), message.end());
}
使用该代码,logSize
被 returned 为 1,这意味着我无法访问 GL 提供的错误消息。据我所知,该消息根本不存在。我已经看到 here 发布的问题,其中的问题是缺少对 glCompileShader
的调用。如您所见,我的代码确实调用了该函数。
在尝试解决这个问题时,我已经确认了一些事情。
- 我的着色器源代码(字符串)正在被正确读取。源是一个字符串,据我所知,它与实际的着色器文件完全匹配。
- 从字符串源到
GLchar const*
或 GLint
(变量 file
和 length
)没有转换问题。两者看起来都正确。
- 如果我人为地增加
logSize
的值(例如,1000),结果消息只是零。不存在错误消息。
- 我在代码中到达这一点之前调用了
glfwInit()
和相关函数。查询 glGetString(GL_VERSION)
正确 return 目标版本 (3.3.0)。
有谁知道如何解决这个问题?正如我所说,我的进度完全受阻,因为我无法在没有工作着色器的情况下渲染任何东西(2D 或 3D)。
谢谢!
问题是您从未将任何着色器源上传到着色器。
这一行的第二个参数:
glShaderSource(shaderId, 0, &file, &length);
告诉 OpenGL 将 0 个代码字符串加载到着色器(无)。将其更改为 1,它应该可以工作。
我正在使用 OpenGL 和 C++ 构建游戏。我正在使用 GLFW 和 GLAD。我目前正在设置简单的着色器,但编译问题完全阻碍了我。简而言之,着色器编译失败,没有错误消息。
这是我的顶点着色器(用于绘制 2D 图像和文本):
#version 330 core
layout (location = 0) in vec2 vPosition;
layout (location = 1) in vec2 vTexCoords;
layout (location = 2) in vec4 vColor;
out vec4 fColor;
out vec2 fTexCoords;
uniform mat4 mvp;
void main()
{
vec4 position = mvp * vec4(vPosition, 0, 1);
position.y *= -1;
gl_Position = position;
fColor = vColor;
fTexCoords = vTexCoords;
}
下面是创建着色器、加载着色器源代码、编译着色器和检查错误的相关代码。
GLuint shaderId = glCreateShader(GL_VERTEX_SHADER);
std::string source = FileUtilities::ReadAllText(Paths::Shaders + filename);
GLchar const* file = source.c_str();
GLint length = static_cast<GLint>(source.size());
glShaderSource(shaderId, 0, &file, &length);
glCompileShader(shaderId);
GLint status;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
GLint logSize = 0;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logSize);
std::vector<GLchar> message = std::vector<GLchar>(logSize);
glGetShaderInfoLog(shaderId, logSize, nullptr, &message[0]);
glDeleteShader(shaderId);
std::cout << std::string(message.begin(), message.end());
}
使用该代码,logSize
被 returned 为 1,这意味着我无法访问 GL 提供的错误消息。据我所知,该消息根本不存在。我已经看到 here 发布的问题,其中的问题是缺少对 glCompileShader
的调用。如您所见,我的代码确实调用了该函数。
在尝试解决这个问题时,我已经确认了一些事情。
- 我的着色器源代码(字符串)正在被正确读取。源是一个字符串,据我所知,它与实际的着色器文件完全匹配。
- 从字符串源到
GLchar const*
或GLint
(变量file
和length
)没有转换问题。两者看起来都正确。 - 如果我人为地增加
logSize
的值(例如,1000),结果消息只是零。不存在错误消息。 - 我在代码中到达这一点之前调用了
glfwInit()
和相关函数。查询glGetString(GL_VERSION)
正确 return 目标版本 (3.3.0)。
有谁知道如何解决这个问题?正如我所说,我的进度完全受阻,因为我无法在没有工作着色器的情况下渲染任何东西(2D 或 3D)。
谢谢!
问题是您从未将任何着色器源上传到着色器。
这一行的第二个参数:
glShaderSource(shaderId, 0, &file, &length);
告诉 OpenGL 将 0 个代码字符串加载到着色器(无)。将其更改为 1,它应该可以工作。