glShaderSource参数的含义是什么?

Ros*_*ose 16 c++ opengl

我已经尽力了解OpenGL的功能,但我glShaderSource的参数存在问题:

void glShaderSource(
  GLuint shader,
  GLsizei count,
  const GLchar * const * string,
  const GLint * length);
Run Code Online (Sandbox Code Playgroud)

我对最后两个参数感到困惑.它们在C++中实际意味着什么?这是否意味着我给它一个字符串,一个const char或一个字符串的指针,如果那可能的话?为什么?

Lar*_*und 27

glShaderSource 期望两个相关的序列(C样式数组)的值.

第一个序列是C字符串数组,无论是否为零终止.

第二个序列是整数数组,表示第一个序列中每个字符串的长度.如果字符串是零终止的,则此序列是可选的,因为库将自己找到长度.

GL前缀类型是因为OpenGL规范需要讨论类型而不将其自身绑定到特定语言,因此它引入了常见C类型的别名.

GLchar是一种类似C的类型char,用于表示一个狭窄的角色. GLint是有符号整数类型,通常用于表示对象句柄和偏移量.还有其他人喜欢GLenumGLvoid.

GLchar const*是该char const*类型的OpenGL拼写.除了用于指向单个字符外,它通常用于表示一串字符.当以该含义使用时,它应指向一个字符序列,以sentinel值结束'\0'以知道字符串结束.

制作glShaderSource多个字符串的原因是因为OpenGL的着色器编译器暴露了文件的概念.这些字符串中的每一个都代表一个文件的内容,它将进行编译,就好像这些文件连接在一起一样.请注意,此文件与同名的文件系统事物基本无关.glShaderSource仅处理包含文本的字符串.

当你想要将一些片段组装到完整的着色器源中时,这很有用,比如你想要预先添加一个#version语句或一些常见的前导码,或者你自己实现了某种包含指令.

至于如何使用它的一个例子:

std::string v = "#version 150\n";
std::string c = ReadTextFile("common.glsl"); // read a string with the file contents
std::string s = ReadTextFile("mesh.vert");   // same here

GLchar const* files[] = { v.c_str(), c.c_str(), s.c_str() };
GLint lengths[]       = { v.size(),  c.size(),  s.size()  };

glShaderSource(id, 3, files, lengths);
Run Code Online (Sandbox Code Playgroud)

在这里,我们将OpenGL的三个字符串组合为一大块源文本.请注意,我的便捷功能ReadTextFile将文件系统文件的内容读入字符串,OpenGL的任何部分都没有触及文件系统.如果要将文本文件,图像文件或网格文件的内容放入OpenGL结构中,则需要提前自己阅读.


小智 12

让我们一步一步地完成:

  • const GLchar 是一个不可变(常量)字符.
  • const GLchar *是指向不可变GLchars 的指针,在本例中是您的着色器源.
  • const GLchar * const是指向不可变s 的不可变指针GLchar,这意味着指针本身不能更改为指向其他位置.
  • const GLchar * const *是指向不可变GLchars 的不可变指针的指针.
  • 最后string只是参数的名称.

这意味着它需要一个指向常量GLchars 的常量指针.您可以像这样使用它(使用NULL作为大小,以便计算glShaderSource出长度):

const GLchar *source = "my awesome shader";
glShaderSource(myShader, 1, &source, NULL);
Run Code Online (Sandbox Code Playgroud)

或者指定多个来源:

const GLchar *sources[] = {
  "my awesome shader",
  "another awesome"
};
glShaderSource(myShader, sizeof(sources)/sizeof(*sources), sources, NULL);
Run Code Online (Sandbox Code Playgroud)

我实际上没有测试过上面的代码,可能需要一些演员表,但它应该原则上说明它是如何工作的.