如何在glsl中编写基本着色器?

Vei*_*hen 3 c++ opengl glsl

所以当我学习OpenGL时,我偶然发现了与GLSL有关的问题.这是一本书的引用:

"我们需要做的第一件事是在着色器语言GLSL中编写顶点着色器,然后编译这个着色器,以便我们可以在我们的应用程序中使用它."

然后提供的源代码:

#version 330 core
layout (location=0)in vec3 position;
void main()
{
gl_Position=vec4(position.x, position.y,position.z,1.0);
};
Run Code Online (Sandbox Code Playgroud)

起初我很眩目.这不能写在我的.cpp文件中,因为它不像C一样.我知道我应该创建.glsl文件或其他东西,但书中没有具体说明.然后我找到了一个示例代码(这是用.cpp编写的):

//Shaders
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location=0)in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position=vec4(position.x, position.y,position.z,1.0);\n"
"}\0";
Run Code Online (Sandbox Code Playgroud)

......确实有效.但为什么?是将字符串转换为文件然后以某种方式通过该方法读取glShaderSource();?这一切都没有在书中解释过.

我的问题:

- 这个方法如何使用字符串作为参数并读取代码?

- 这确实是一个冗长的方式.例如,我需要为每一行输入""和"\n".否则,没有'\n',它将是非常无组织和丑陋的.有替代方法吗?

任何帮助是极大的赞赏.

Nic*_*las 7

该方法如何使用字符串作为参数并读取代码?

...通过使用字符串作为参数并阅读代码.我知道这听起来很轻浮,但这正是它的工作原理.

字符串只是一个字符串.您可以在C++中使用字符串文字并读取它:

const char *str = "Here is a string.";
std::cout << str[3];
Run Code Online (Sandbox Code Playgroud)

这将打印出"e",因为这是字符串中的第4个字母.

OpenGL正在做的是读取该字符串并对其进行处理.它识别并理解GLSL的语法,将文本转换为它需要的任何内部表示,以便执行GPU上该字符串描述的代码.实际上,它正在执行您的C++编译器所做的事情,但它正在您的应用程序运行时执行此操作.

这确实是一个冗长的方式.例如,我需要为每一行输入""和"\n".否则,没有'\n',它将是非常无组织和丑陋的.

不,你没有.在C++ 11(几乎所有现代编译器都支持)中,您可以使用原始字符串文字:

const GLchar *vertexShaderSource = R"(
#version 330 core
layout (location=0)in vec3 position;
void main()
{
    gl_Position=vec4(position.x, position.y,position.z,1.0);
};)";
Run Code Online (Sandbox Code Playgroud)

原始字符串文字在遇到a时结束)".并且由于该"字符未在GLSL中使用,因此只有在完成后才会遇到此问题

有替代方法吗?

您可以从文件中加载它.你可以从几十个文件中拼凑起来.你可以在同一个文件中有几十个着色器,使用特殊字符让你知道一个开始和另一个结束.您可以从SQLite数据库中检索它们.您可以根据从其他内容读取的一些基本参数手动构建此类字符串.您可以从文件加载字符串并对其执行一些正则表达式替换操作.还有很多其他选择.

OpenGL 并不关心.OpenGL唯一关心的是,当你调用时glShaderSource,你给它的字符串必须符合OpenGL着色语言的语法.

如何获得这样的字符串不是OpenGL的业务.