Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to write basic shader in glsl?

Tags:

c++

opengl

glsl

This is the quote from a book:

"The first thing we need to do is write the vertex shader in the shader language GLSL and then compile this shader so we can use it in our application."

And then the source code provided:

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

I was dazzled at first. This cannot be written inside my .cpp file, because it was nothing C-like. I know I should create a .glsl file or something, but there were no specific instructions in the book. Then I found an example code (This was written in the .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";

...And indeed it worked. But why? Was the string converted into a file and then somehow read by the method glShaderSource();? All this wasn't explained in the book.

My question:

  • How does this method use a string as an argument and read the code?
  • This is indeed a lengthy way. For example, I need to type " " and '\n' for every line. Else, it would be very unorganized and ugly without the '\n's. Is there an alternative method?
like image 251
Veii Xhen Avatar asked Jan 04 '23 06:01

Veii Xhen


1 Answers

How does this method use a string as an argument and read the code?

... by using the string as an argument and reading the code. I know that sounds flippant, but that's exactly how it works.

A string is just a string. You can take a string literal in C++ and read through it:

const char *str = "Here is a string.";
std::cout << str[3];

That will print out "e", because that's the 4th letter in the string.

What OpenGL is doing is reading that string and processing it. It recognizes and understands GLSL's grammar, transforming the text into whatever internal representation it needs to in order to execute the code described by that string on the GPU. In effect, it's doing what your C++ compiler does, but it's doing it while your application is running.

This is indeed a lengthy way. For example, I need to type " " and '\n' for every line. Else, it would be very unorganized and ugly without the '\n's.

No, you don't. In C++11 (which virtually all modern compilers support), you can use raw string literals:

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);
};)";

Raw string literals end when they encounter a )". And since the " character isn't used within GLSL, it will only encounter this when you're done with the literal.

Is there an alternative method?

You could load it from a file. You could piece it together from dozens of files. You could have dozens of shaders in the same file, with special characters used to let you know where one starts and another ends. You could retrieve them from an SQLite database. You could manually build such a string based on some basic parameters you read from something else. You could load a string from a file and do some regex-replacement operations on it. And many other alternatives.

OpenGL does not care. The only thing that OpenGL cares about is that, when you call glShaderSource, the string(s) you give it must conform to the grammar of the OpenGL Shading Language.

How you get such a string is none of OpenGL's business.

like image 115
Nicol Bolas Avatar answered Jan 15 '23 07:01

Nicol Bolas