函数名称
glShaderSource —— 用于将GLSL代码从字符串载入着色器对象中
函数声明
void glShaderSource(GLuint shader,
GLsizei count,
const GLchar **string,
const GLint *length);
函数参数(Parameters)
shader
: 指定要载入GLSL代码的着色器对应的ID,一般这个ID通过函数glCreateShader()
取得,为GLuint
类型count
: 着色器源代码中的字符串数量,为GLsizei
类型string
: 指定指向字符串的指针数组,这些字符串包含要加载到着色器中的源代码,为const GLchar **
类型length
: 指定字符串长度的数组,为const GLint *
类型
关于函数参数的说明
网上的大多教程都没有深入说明后两个参数string
、length
到底是个啥,单凭抽象的文字描述也很难体会,此处做出我的理解的特殊说明。
以下内容为个人理解,若有偏差,造成的任何后果本人概不负责
string
: 其应该是一个元素类型为字符串数组的数组,这个数组里面的每一个元素应该都是一个字符串数组(这个字符串数组存放GLSL代码)字符串数组
:这个内容不必多言,应该是基础的C/C++的内容,例如下面的vvshaderSource
便是一个字符串数组元素类型为字符串数组的数组
: 也很好理解,如果一个数组里的元素是一个个字符串数组,那么它就是元素类型为字符串数组的数组,例如下面的vvvshaderSource
就是一个元素类型为字符串数组的数组
const char* vvshaderSource = "#version 430\nvoid main(void)\n{gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}" ; /* 71 */
const char* vvvshaderSource[1] = { vvshaderSource };
length
: 它与上一个参数string
对应,是一个整型数组,数组中的每一个元素分别对应string
中的每个元素的长度,例如下面的vlength
就可以是上面的vvvshaderSource
对应的length
。此外,这个参数还可以输入NULL
,意味着string
中的每个字符串都以null
结尾(也即你指定了以null
结尾,那么程序会自己数你这个字符串多长,就不需要你指定啦!),输入负数的效果和输入NULL
一致
const GLint vlength[1] = { 71 };
则我们可以如下调用函数glShaderSource()
glShaderSource(vShader, 1, vvvshaderSource, vlength);
函数介绍
glShaderSource()
将着色器中的源代码设置为字符串指定的字符串数组中的源代码。以前存储在着色器对象中的任何源代码都将被完全替换。此时不扫描或解析源代码字符串;它们只是复制到指定的着色器对象中。
注意事项
调用 glShaderSource 时,OpenGL 会复制着色器源代码字符串,因此应用程序可以在函数返回后立即释放其源代码字符串的副本,这样可以节省开销
使用实例
#include <gl\glew.h>
#include <GLFW\glfw3.h>
#include <iostream>
using namespace std;
#define numVAOs (1U)
GLuint renderingProgram; /* rendering: 渲染 Program: 程序 */
GLuint vao[numVAOs]; /* vao: 顶点 在OpenGL程序中常用来当作顶点数组 */
GLuint createShaderProgram()
{
const char* vvshaderSource = "#version 430\nvoid main(void)\n{gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}" ; /* 71 */
const char* vvvshaderSource[1] = { vvshaderSource };
const char* ffshaderSource = "#version 430\nout vec4 color;\nvoid main(void)\n{color = vec4(0.0, 0.0, 1.0, 1.0);}" ; /* 81 */
const char* fffshaderSource[1] = { ffshaderSource };
const GLint vlength[1] = { 71 };
const GLint flength[1] = { 81 };
GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vShader, 1, vvvshaderSource, vlength);
glShaderSource(fShader, 1, fffshaderSource, flength);
glCompileShader(vShader);
glCompileShader(fShader);
GLuint vfProgram = glCreateProgram();
glAttachShader(vfProgram, vShader);
glAttachShader(vfProgram, fShader);
glLinkProgram(vfProgram);
return vfProgram;
}
void init(GLFWwindow* window)
{
renderingProgram = createShaderProgram();
glGenVertexArrays(numVAOs, vao);
glBindVertexArray(vao[0]);
}
void display(GLFWwindow* window, double currentTime)
{
glUseProgram(renderingProgram);
glDrawArrays(GL_POINTS, 0, 1);
}
int main(void) {
if (!glfwInit()) { exit(EXIT_FAILURE); }
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* window = glfwCreateWindow(800, 400, "Chapter2 - program1", NULL, NULL);
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
glfwSwapInterval(1);
init(window);
while (!glfwWindowShouldClose(window)) {
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
效果说明:会在创建的小窗口中央画一个蓝色小点