glGetShaderInfoLog详解

官方文档

​官网文档​​​ Name
glGetShaderInfoLog — Returns the information log for a shader object

C Specification
void glGetShaderInfoLog( GLuint shader,
GLsizei maxLength,
GLsizei *length,
GLchar *infoLog);

Parameters
shader
Specifies the shader object whose information log is to be queried.

maxLength
Specifies the size of the character buffer for storing the returned information log.

length
Returns the length of the string returned in infoLog (excluding the null terminator).

infoLog
Specifies an array of characters that is used to return the information log.

Description
glGetShaderInfoLog returns the information log for the specified shader object. The information log for a shader object is modified when the shader is compiled. The string that is returned will be null terminated.

glGetShaderInfoLog returns in infoLog as much of the information log as it can, up to a maximum of maxLength characters. The number of characters actually returned, excluding the null termination character, is specified by length. If the length of the returned string is not required, a value of NULL can be passed in the length argument. The size of the buffer required to store the returned information log can be obtained by calling glGetShader with the value GL_INFO_LOG_LENGTH.

The information log for a shader object is a string that may contain diagnostic messages, warning messages, and other information about the last compile operation. When a shader object is created, its information log will be a string of length 0.

Notes
The information log for a shader object is the OpenGL implementer’s primary mechanism for conveying information about the compilation process. Therefore, the information log can be helpful to application developers during the development process, even when compilation is successful. Application developers should not expect different OpenGL implementations to produce identical information logs.

Errors
GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.

GL_INVALID_OPERATION is generated if shader is not a shader object.

GL_INVALID_VALUE is generated if maxLength is less than 0.

Associated Gets
glGetShader with argument GL_INFO_LOG_LENGTH

glIsShader

Version Support
OpenGL Version
Function / Feature Name 2.0 2.1 3.0 3.1 3.2 3.3 4.0 4.1 4.2 4.3 4.4 4.5
glGetShaderInfoLog ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
See Also
glCompileShader, glGetProgramInfoLog, glLinkProgram, glValidateProgram

Copyright
Copyright © 2003-2005 3Dlabs Inc. Ltd. Copyright © 2010-2014 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/.

翻译

名称
glGetShaderInfoLog ---- 返回 shader 对象的日志信息。

原型

void glGetShaderInfoLog(GLuint shader,
GLsizei maxLength,
GLsizei *length,
GLchar *infoLog);

参数
shader
指定需要查询日志信息的 shader 对象。
maxLength
指定储存日志信息的字符缓存大小。
length
返回 infoLog(不包括空结尾符)的字符串长度。
infoLog
指定用于返回日志信息的字符数组。

描述
glGetShaderInfoLog 返回指定 shader 对象的日志信息。一个shader 对象的日志信息会在 shader 编译是修改。返回的字符串将以空字符结尾。

glGetShaderInfoLog 返回 infoLog 的maxLength最大长度的字符的能填入的日志信息。返回的是实际的字符需要的数量,不包含空结尾符,而是指定 length 的长度。如果不需要返回字符串的长度,那么 length 传入 NULL。获取需要日志信息缓存的大小,可通过 只用 GL_INFO_LOG_LENGTH 来调用 glGetShader 。

一个 shader 对象的日志信息可能包含诊断信息,警告信息,和其他关于编译操作的信息。当一个 shader 对象被创建时,它的日志信息将会被设置为一个 0 长度的字符串。

注意
一个 shader 对象的日志信息是 OpenGL 实现的编译相关过程的主要机制。因此,日志信息对于应用程序开发者在开发过程是很有帮助的,即使编译是成功的。

错误
如果 shader 参数不是 OpenGL 生成的,那么生成 GL_INVALID_VALUE 错误。

如果 shader 参数不是一个 shader 对象,那么省 GL_INVALID_OPERATION 错误。

如果 maxLength 小于0,那么生成 GL_INVALID_VALUE 错误。

例子

#include "glew/glew.h"
#include "glfw/glfw3.h"
//#include "freetype/freetype.h"
#include <iostream>

using namespace std;

static const int scr_width = 800;
static const int scr_height = 600;
static const int numVAOs = 1;

GLuint renderingProgram = 0;
GLuint vao[numVAOs] = { 0 };

void printShaderLog(GLuint shader)
{
int nLen = 0;
int nWrittn = 0;
char* chLog = nullptr;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &nLen);
if (nLen > 0)
{
char* chLog = (char*)malloc(nLen);
if (!chLog)
{
cout << "Allocate memory failed. Invoke malloc()." << std::endl;
return;
}
/* 功能: 获取着色器程序编译错误信息,glGetShaderiv()一个 shader 对象的日志信息可能包含诊断信息,警告信息,和其他关于编译操作的信息
* vShader: 用来存放着色器对象
* nLen: 指定储存日志信息的字符缓存大小
* &nWrittn: 返回 chLog(不包括空结尾符)的字符串实际长度
* chLog 指定用于返回日志信息的字符数组
*/
glGetShaderInfoLog(shader, nLen, &nWrittn, chLog);
cout << "Shader infomation log:" << chLog << std::endl;
free(chLog);
}
}

void printProgramInfo(GLuint nProgram)
{
int nLen = 0;
int nWrittn = 0;
char* chLog = nullptr;
glGetProgramiv(nProgram, GL_INFO_LOG_LENGTH, &nLen);
if (nLen > 0)
{
chLog = (char*)malloc(nLen);
if (!chLog)
{
cout << "Allocate memory failed! Invoke malloc()." << std::endl;
return;
}
glGetProgramInfoLog(nProgram, nLen, &nWrittn, chLog);
cout << "Program infomation log:" << chLog << std::endl;
free(chLog);
}
}

bool checkOpenglError()
{
bool foundError = false;
int glErr = glGetError();
while (glErr != GL_NO_ERROR)
{
cout << "Opengl Error:" << glErr << std::endl;
foundError = true;
glErr = glGetError();
}

return foundError;
}

GLuint createShaderProgram()
{
GLint vertCompiled = 0;
GLint fragCompiled = 0;
GLint linked = 0;

const char* vShaderSource =
"#version 430 core core \n"
"void main() \n"
"{ \n"
" gl_Position = vec4(0.f, 0.f, 0.f, 1.f); \n"
"}";
const char* fShaderSource =
"#version 430 core \n"
"out vec4 outColor; \n"
"void main() \n"
"{ \n"
" outColor = vec4(0.5f, 1.f, 0.5f, 1.f); \n"
"}";
GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
GLuint vfProgram = glCreateProgram();

glShaderSource(vShader, 1, &vShaderSource, nullptr);
glShaderSource(fShader, 1, &fShaderSource, nullptr);

glCompileShader(vShader);
checkOpenglError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);

int glErr = glGetError();
if (GL_FALSE == vertCompiled)
{
checkOpenglError();
cout << "Vertex shader compilation failed. Invoke glGetShaderiv()." << std::endl;
printShaderLog(vShader);
}
else
{
cout << "Vertex shader compilation failed. Invoke glGetShaderiv(vShader)." << std::endl;
printShaderLog(vShader);
}

glCompileShader(fShader);
checkOpenglError();
glGetShaderiv(fShader, GL_COMPILE_STATUS, &fragCompiled);
if (GL_TRUE == fragCompiled)
{
cout << "Fragment shader compilation success." << std::endl;
}
else
{
cout << "Fragment shader compilation failed. Invoke glGetShaderiv(fShader)." << std::endl;
printShaderLog(fShader);
}

glAttachShader(vfProgram, vShader);
glAttachShader(vfProgram, fShader);
glLinkProgram(vfProgram);
checkOpenglError();
glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
if (GL_TRUE == linked)
{
cout << "Program link success." << std::endl;
}
else
{
cout << "Program link failed. Invoke glGetProgramiv()." << std::endl;
printProgramInfo(vfProgram);
}

return vfProgram;
}

void init(GLFWwindow* window)
{
renderingProgram = createShaderProgram();
glGenVertexArrays(numVAOs, vao);
glBindVertexArray(vao[0]);
//加载字体
//g_FreeTypeLib.load("c://windows//fonts//simhei.ttf", 12, 12);
}

void display(GLFWwindow* window, double currentTime)
{
glUseProgram(renderingProgram);
glPointSize(150.f);
glDrawArrays(GL_POINTS, 0, 1);
}

int main()
{
if (!glfwInit())
{
exit(EXIT_FAILURE);
}

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);

GLFWwindow* window = glfwCreateWindow(scr_width, scr_height, "Draw point with check error", nullptr, nullptr);
if (!window)
{
cout << "GLFW create window failed. Invoke glfwCreateWindow()." << std::endl;
glfwTerminate();
exit(EXIT_FAILURE);
}

glfwMakeContextCurrent(window);

if (glewInit() != GLEW_OK)
{
cout << "GLEW initialize failed. Invoke glewInit()." << std::endl;
exit(EXIT_FAILURE);
return -1;
}
//由于这些原因,应用程序通常希望将交换间隔设置为1。可以将其设置为更高的值,但通常不建议这样做,因为这样会导致输入延迟。
glfwSwapInterval(1);

init(window);

while (!glfwWindowShouldClose(window))
{
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}

glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);

return 0;
}

代码分析

在82行代码,我故意写错:多写了一个 core

openGL API glGetShaderInfoLog函数详解_openGL着色器编译错误

glGetShaderInfoLog输出错误

chLog变量输出错误信息:

openGL API glGetShaderInfoLog函数详解_openGL着色器编译错误_02


可以看出glGetShaderInfoLog确实捕获到了着色器的语法错误,多写了一个“core”

openGL API glGetShaderInfoLog函数详解_glGetShaderInfo_03

工程下载

​源码工程下载​