1.GLSL错误
编译和运行GLSL代码与普通代码不一样。GLSL编译发生于C++运行时。更复杂的是GLSL代码运行在GPU中(而不是CPU)因此不易捕获错误。
为此GLSL提供了glGetShaderiv()和glGetProgramiv()用于提供有关编译过的GLSL着色器和程序的信息。
glGetShaderiv();
参数:1.shader:要查询的着色器对象标识符。
2.pname:指定要查询的参数名称,如编译状态、着色器类型等。
3.params:用于存储返回结果的参数数组。
作用;获取指定着色器对象的相关参数信息,如编译状态、信息日志长度等。(具体取决于 pname 参数指定的查询类型,例如可以通过 GL_COMPILE_STATUS 查询编译状态,通过 GL_INFO_LOG_LENGTH 查询信息日志长度等。)
glGetProgramiv();
参数;1.program:要查询的程序对象标识符。
2.pname:指定要查询的参数名称,如链接状态、程序二进制长度等。
3.params:用于存储返回结果的参数数组。
作用;获取指定程序对象的相关参数信息,如链接状态、程序二进制长度等。类似于 glGetShaderiv(),具体取决于 pname 参数指定的查询类型。
2.OpenGL错误
checkOpenGLError();用于检查OpenGL错误日志,确认是否发生OpenGL错误
printShaderLog();当GLSL编译失败时,显示OpenGL日志内容
printProgramLog();当GLSL链接失败时,显示OpenGL日志内容
其中 checkOpenGLError()既用于检测GLSL编译错误,又用于OpenGL运行时错误;
参考代码:
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<iostream>
#define numVAOs 1
using namespace std;
GLuint renderingProgram;
GLuint vao[1];
GLuint createShaderProgram() {
void printShaderLog(GLuint shader);
void printProgramLog(int prog);
bool checkOpenGLError();
GLint vertCompiled;
GLint fragCompiled;
GLint linked;
const char* vshaderSource =
"#version 430 \n"
"void main(void) \n"
"{gl_Position = vec4(0.0,0.0,0.0,1.0); }";
const char* fshaderSource =
"#version 430 \n"
"out vec4 color; \n"
"void main(void) \n"
"{if(gl_FragCoord.x<350) color = vec4(1.0,0.0,0.0,1.0); else color = vec4(0.0,0.0,1.0,1.0); }";
GLuint vShader = glCreateShader(GL_VERTEX_SHADER);//创建着色器
GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vShader, 1, &vshaderSource, NULL);//将GLSL代码从字符串载入着色器对象中
glShaderSource(fShader, 1, &fshaderSource, NULL);
glCompileShader(vShader);//编译着色器
//捕获编译着色器时的错误
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
if (vertCompiled != 1) {
cout << "vertx compilation failed" << endl;
printShaderLog(vShader);
}
glCompileShader(fShader);
//捕获编译着色器时的错误
checkOpenGLError();
glGetShaderiv(fShader,GL_COMPILE_STATUS,&fragCompiled);
if (fragCompiled != 1) {
cout << "fragment compilation failed" << endl;
printShaderLog(fShader);
}
GLuint vfProgram = glCreateProgram();//创建程序对象
glAttachShader(vfProgram, vShader); //将着色器载入程序
glAttachShader(vfProgram, fShader);
glLinkProgram(vfProgram); //请求GLSL编译器确保兼容性
//捕获链接着色器时的错误
checkOpenGLError();
glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
if (linked != 1) {
cout << "linkeding failed" << endl;
printProgramLog(vfProgram);
}
return vfProgram;
}
void init(GLFWwindow* window) {
glewExperimental = GL_TRUE;
glewInit();
renderingProgram = createShaderProgram();
glGenVertexArrays(numVAOs, vao);
glBindVertexArray(vao[0]);
}
void display(GLFWwindow* window, double currentTime) {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(renderingProgram); //
glPointSize(30.0f); //点的尺寸
glDrawArrays(GL_POINTS, 0, 1); //图元类型,从哪里开始绘制,绘制顶数
}
int main(void) {
if (!glfwInit()) {
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);//指定OpenGL版本
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* window = glfwCreateWindow(700, 700, "weindows", NULL, NULL);//创建窗口
glfwMakeContextCurrent(window); //关联上下文
if (glewInit() != 0) {
exit(EXIT_FAILURE); //异常退出
}
glfwSwapInterval(1); //刷新每帧刷新一次;
init(window); //调用init函数
while (!glfwWindowShouldClose(window)) {
display(window, glfwGetTime()); //调用display函数
glfwSwapBuffers(window); //绘制窗口
glfwPollEvents(); //处理窗口相关事件
}
glfwDestroyWindow(window); //销毁窗口
glfwTerminate(); //终止运行
exit(EXIT_SUCCESS); //正常退出
}
//检查着色器编译是否成功的函数
void printShaderLog(GLuint shader) {
int len = 0;
int chWrittn = 0;
char* log;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetShaderInfoLog(shader, len, &chWrittn, log);
cout << "Shader Inof Log:" << log << endl;
free(log);
}
}
//捕获链接着色器时的错误的函数
void printProgramLog(int prog) {
int len = 0;
int chWrittn = 0;
char* log;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetProgramInfoLog(prog, len, &chWrittn, log);
cout << "Program Inof Log:" << log << endl;
free(log);
}
}
//检查OpenGL是否错误的函数
bool checkOpenGLError() {
bool foundError = false;
int glErr = glGetError();
while (glErr != GL_NO_ERROR) {
cout << "glError:" << glErr << endl;
foundError = true;
glErr = glGetError();
}
return foundError;
}