glGetShaderiv函数详解

glGetShaderiv是一个OpenGL函数,用于获取着色器对象的各种参数,如类型、删除状态、编译状态、信息日志长度和源码长度。通过指定着色器对象和参数名,可以检查着色器是否成功编译,是否存在删除标记,以及获取相关信息。错误处理包括无效值、无效操作和无效枚举。示例代码展示了如何使用glGetShaderiv检查着色器编译日志。
摘要由CSDN通过智能技术生成

前言

Name
glGetShaderiv — Returns a parameter from a shader object

C Specification
void glGetShaderiv( GLuint shader,
GLenum pname,
GLint *params);

Parameters
shader
Specifies the shader object to be queried.

pname
Specifies the object parameter. Accepted symbolic names are GL_SHADER_TYPE, GL_DELETE_STATUS, GL_COMPILE_STATUS, GL_INFO_LOG_LENGTH, GL_SHADER_SOURCE_LENGTH.

params
Returns the requested object parameter.

Description
glGetShader returns in params the value of a parameter for a specific shader object. The following parameters are defined:

GL_SHADER_TYPE
params returns GL_VERTEX_SHADER if shader is a vertex shader object, GL_GEOMETRY_SHADER if shader is a geometry shader object, and GL_FRAGMENT_SHADER if shader is a fragment shader object.

GL_DELETE_STATUS
params returns GL_TRUE if shader is currently flagged for deletion, and GL_FALSE otherwise.

GL_COMPILE_STATUS
params returns GL_TRUE if the last compile operation on shader was successful, and GL_FALSE otherwise.

GL_INFO_LOG_LENGTH
params returns the number of characters in the information log for shader including the null termination character (i.e., the size of the character buffer required to store the information log). If shader has no information log, a value of 0 is returned.

GL_SHADER_SOURCE_LENGTH
params returns the length of the concatenation of the source strings that make up the shader source for the shader, including the null termination character. (i.e., the size of the character buffer required to store the shader source). If no source code exists, 0 is returned.

Notes
If an error is generated, no change is made to the contents of params.

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

GL_INVALID_OPERATION is generated if shader does not refer to a shader object.

GL_INVALID_ENUM is generated if pname is not an accepted value.

Associated Gets
glGetShaderInfoLog with argument shader

glGetShaderSource with argument shader

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
glGetShaderiv ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
See Also
glCompileShader, glCreateShader, glDeleteShader, glGetProgram, glShaderSource

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/.

翻译

名称
glGetShaderiv - 从着色器对象返回一个参数(用来检测着色器编译是否成功)

规范
void glGetShaderiv(GLuint shader,GLenum pname,GLint *params);

参数
shader
指定要查询的着色器对象,直接放入需要检查的着色器即可。

pname
指定着色器对象的参数。 可接受的符号名称为

(1)GL_SHADER_TYPE:
shader_type:着色器类型
用来判断并返回着色器类型,若是顶点着色器返回GL_VERTEX_SHADER,若为片元着色器返回GL_FRAGMENT_SHADER.

(2)GL_DELETE_STATUS:
detele status:删除状态
判断着色器是否被删除,是返回GL_TRUE,否则返回GL_FALSE,

(3)GL_COMPILE_STATUS:
compile_status:编译状态
用于检测编译是否成功,成功为GL_TRUE,否则为GL_FALSE.

(4)GL_INFO_LOG_LENGTH:
information log length: log是日志的意思,所以是返回着色器的信息日志的长度
用于返回着色器的信息日志的长度,包括空终止字符(即存储信息日志所需的字符缓冲区的大小)。 如果着色器没有信息日志,则返回值0。

(5)GL_SHADER_SOURCE_LENGTH:
SHADER_SOURCE_LENGTH:着色器源码长度
返回着色器源码长度,不存在则返回0;

params
函数将返回的结果存储在输入的第三个参数中,因为这个函数得到的结果有很多种,所以要单独放在第三个参数当中,所以是void glGetShaderiv而不是GLuint。

错误
GL_INVALID_ENUM: pname不是一个可接受的值。

GL_INVALID_VALUE: shader不是OpenGL生成的值。

GL_INVALID_OPERATION: 不支持着色器编译器的情况下查询pname为GL_COMPILE_STATUS,GL_INFO_LOG_LENGTH或GL_SHADER_SOURCE_LENGTH(GL_SHADER_TYPE,GL_DELETE_STATUS不会报这个错)。

GL_INVALID_OPERATION: shader没有关联着色器对象。

例子

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

using namespace std;

static const unsigned int scr_width = 800;
static const unsigned int scr_height = 600;

static const int numVAOs = 1;

GLuint renderingProgram;
GLuint vao[numVAOs];


//错误处理
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);
		//返回指定 shader 对象的日志信息
		glGetShaderInfoLog(shader, len, &chWrittn, log);
		cout << "Shader info Log:" << log << std::endl;
		free(log);
	}
	else
	{
		cout << "Shader compiler failed! Invoke glGetShaderiv()." << std::endl;
		return;
	}
}

void printProgramLong(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 info log:" << log << std::endl;
		free(log);
	}
	else
	{
		cout << "Shader link failed! Invoke glGetProgramiv()." << std::endl;
		return;
	}
}

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

static void error_callback(int error, const char* description)
{
	fprintf_s(stderr, "Error:%s\n", description);
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
	if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(window, GLFW_TRUE);
	}
}


/*
* 顶点着色器:    一次操作一个顶点,显卡是并行处理的
* 片元着色器:    一次操作一个像素(片元)
* 几何着色器:    一次操作一个图元(通常是一个三角形,这时管线已经完成了将顶点组合成三角形的过程,这过程叫图元装配)
* 曲面细分着色器:
* 光栅化:将3D世界中的点、三角形、颜色等显示在一个2D显示器上的过程,光栅化会将对像素进行插值,任何顶点着色器输出的变量和片
* 段着色器的输入变量都可以基于对应的像素进行插值
*/
GLuint createShaderProgram()
{
	const char* vShaderSource =
		"#version 430 core								\n"
		"void main(void)								\n"
		"{												\n"
		"	gl_Position = vec4(0.f, 0.f, 0.f, 1.f);     \n"
		"}												\n";

		const char* fShaderSource =
		"#version 430 core								\n"
		"out vec4 fragColor;							\n"
		"void main(void)								\n"
		"{                                              \n"
		"	fragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);   \n"
		"}												\n";

		GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
		GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);

		/*vShader:        用来存放着色器对象
		* 1:             着色器源代码中的字符串数量
		* &vShaderSource:包含源代码的字符串指针
		* 
		* 
		* 
		
		*/
		glShaderSource(vShader, 1, &vShaderSource, nullptr);
		glShaderSource(fShader, 1, &fShaderSource, nullptr);
		glCompileShader(vShader);
		glCompileShader(fShader);

		//创建程序对象
		GLuint vfProgram = glCreateProgram();
		//将着色器加入程序对象
		glAttachShader(vfProgram, vShader);
		glAttachShader(vfProgram, fShader);
		//链接程序对象来请求GLSL编译器兼容性
		glLinkProgram(vfProgram);

		return vfProgram;
}

void init(GLFWwindow* window)
{
	renderingProgram = createShaderProgram();
	//缓冲区最后都会被存入顶点数组对象VAO(Vertex Array Object)
	glGenVertexArrays(numVAOs, vao);
	glBindVertexArray(vao[0]);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}

void display(GLFWwindow* window, double currentTime)
{
	glClearColor(0.f, 0.f, 1.f, 1.f);
	glClear(GL_COLOR_BUFFER_BIT);
	//将含有两个已编译着色器的程序载入openGL管线阶段(GPU上)
	//注意:glUseProgram()并没有运行着色器,他只是将着色器加载进硬件
	glUseProgram(renderingProgram);
	glPointSize(40.0f);
	//用来启动管线处理过程
	glDrawArrays(GL_POINTS, 0, 1);
}


int main(int argc, char** argv)
{
	int glfwState = glfwInit();
	if (GLFW_FALSE == glfwState)
	{
		cout << "GLFW initialize failed. Invoke glfwInit()." << std::endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	glfwSetErrorCallback(error_callback);

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	GLFWwindow* window = glfwCreateWindow(scr_width, scr_height, "Draw point", nullptr, nullptr);
	if (nullptr == window)
	{
		cout << "GLFW create window failed! Invoke glfwCreateWindow()." << std::endl;
		//释放GLFW所有资源,直到调用glfwInit才能重新获取GLFW资源
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	//用于设置指定窗口的键回调,在按下、重复或释放键时调用该窗口
	glfwSetKeyCallback(window, key_callback);
	
	//调用线程上指定窗口的OpenGL或OpenGL ES上下文成为当前上下文。上下文一次只能在单个线程上成为当前上下文,并且每个线程一次只能有一个当前上下文。
	glfwMakeContextCurrent(window);
	
	int glewState = glewInit();
	if (GLEW_OK != glewState)
	{
		cout << "GLEW initialize failed! Invoke glfwInit()." << std::endl;
		exit(EXIT_FAILURE);
	}

	//由于这些原因,应用程序通常希望将交换间隔设置为1。可以将其设置为更高的值,但通常不建议这样做,因为这样会导致输入延迟。
	glfwSwapInterval(1);

	init(window);

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

	//销毁窗口,以及撤销窗口事件
	glfwDestroyWindow(window);
	glfwTerminate();
	exit(EXIT_SUCCESS);
	return 0;
}




在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值